function PointJS(ea, fa, nb, Dc) {
    this._logo = "http://pointjs.ru/PjsMin.png";
    var g = window,
        q = this,
        Ca = !0,
        ob = !0,
        Kb = !0,
        ka = !1,
        Da = !0,
        l = ea,
        p = fa,
        O = l / 2,
        P = p / 2,
        f = { x: 0, y: 0 },
        t = { fillStyle: "black", strokeStyle: "black", globalAlpha: 1, font: "sans-serif", textBaseline: "top" },
        U = function(a) { console.log(a) };
    "undefined" != typeof POINTJS_USER_LOG && (U = POINTJS_USER_LOG);
    var Oa = function(a) {
        var b = decodeURI(a.stack.toString().replace(/(@|[\(\)]|[\w]+:\/\/)/g, ""));
        b = b.split(/\n/);
        b = ("" == b[2] ? b[0] : b[1]).split("/");
        b = b[b.length -
            1].split(":");
        U('ERROR "' + a.toString() + '" \n in      ' + b[0] + " \n line :   " + b[1] + " \n symbol : " + b[2])
    };
    this.game = {};
    this.levels = {};
    this.camera = {};
    this.keyControl = {};
    this.mouseControl = {};
    this.touchControl = {};
    this.actionControl = {};
    this.system = {};
    this.vector = {};
    this.math = {};
    this.layers = {};
    this.colors = {};
    this.brush = {};
    this.audio = {};
    this.wAudio = {};
    this.resources = {};
    this.tiles = {};
    this.OOP = {};
    this.memory = {};
    this.zList = {};
    this.filters = {};
    this.system.log = U;
    this.system.consoleLog = function(a) {
        this.log = !0 ===
            a ? console.log : U
    };
    this.system.setTitle = function(a) { g.document.title = a };
    this.system.setSettings = function(a) { Ca = u(a.isShowError) ? a.isShowError : !0;
        ob = u(a.isStopForError) ? a.isStopForError : !0;
        Kb = u(a.isAutoClear) ? a.isAutoClear : !1;
        u(a.isZBuffer) };
    this.system.setDefaultSettings = function(a) { for (var b in a) t[b] = a[b];
        h.save() };
    this.system.setSmoothing = function(a) { Da = a;
        h.msImageSmoothingEnabled = Da;
        h.imageSmoothingEnabled = Da };
    var qc = {
        name: "PointJS",
        desc: "HTML5 Game Engine for JavaScript",
        author: "Skaner (skaner0@yandex.ru)",
        version: "0.2.2"
    };
    this.system.getInfo = function() { return qc };
    var ba = function(a, b) { b.prototype = Object.create(a.prototype);
            b.prototype.constructor = b },
        ha = function(a, b, c) { this.x = a || 0;
            this.y = b || 0;
            this.z = c || 0 };
    ha.prototype = {
        abs: function() { return new ha(Math.abs(this.x), Math.abs(this.y), Math.abs(this.z)) },
        invert: function() { return new ha(-this.x, -this.y, -this.z) },
        plus: function(a) { return new ha(this.x + a.x, this.y + a.y, this.z + a.z) },
        minus: function(a) { return new ha(this.x - a.x, this.y - a.y, this.z - a.z) },
        inc: function(a) {
            return new ha(this.x *
                a.x, this.y * a.y, this.z * a.z)
        },
        div: function(a) { return new ha(this.x / a.x, this.y / a.y, this.z / a.z) }
    };
    var e = function(a, b, c) { return new ha(a, b, c) },
        C = function(a, b, c) { return { w: a, h: b, d: c } },
        ua = function(a, b) { return { x: a.x + b.x, y: a.y + b.y, z: a.z + b.z } },
        E = function(a, b, c) { if (0 != c) { var d = x(c);
                c = a.x - b.x;
                a = a.y - b.y; var n = Math.cos(d);
                d = Math.sin(d); return e(c * n - a * d + b.x, c * d + a * n + b.y) } return e(a.x, a.y) },
        Ea = function(a, b) { return 180 / Math.PI * Math.atan2(b.y - a.y, b.x - a.x) },
        la = function(a, b) {
            var c, d = 0;
            var n = 0;
            var e = b.length;
            for(c = b.length-1; n<e; c = n++)
            	b[n].y > a.y != b[c].y > a.y && a.x < (b[c].x - b[n].x) * (a.y - b[n].y) / (b[c].y - b[n].y) + b[n].x && (d = !d);
            return d
        };
    this.vector.point = e;
    this.vector.v2d = e;
    this.vector.size = C;
    this.vector.getPointAngle = E;
    this.vector.isPointIn = la;
    this.vector.pointMinus = function(a, b) { return { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z } };
    this.vector.pointPlus = ua;
    this.vector.pointInc = function(a, b) { return { x: a.x * b.x, y: a.y * b.y, z: a.z * b.z } };
    this.vector.pointDiv = function(a, b) { return { x: a.x / (0 != b.x ? b.x : 1), y: a.y / (0 != b.y ? b.y : 1), z: a.z / (0 != b.z ? b.z : 1) } };
    this.vector.pointAbs = function(a) { return { x: Math.abs(a.x), y: Math.abs(a.y), z: Math.abs(a.z) } };
    this.vector.getMidPoint = function(a, b) { return u(b) ? e((a.x + b.x) / 2, (a.y + b.y) / 2) : 0 };
    this.vector.getDistance = function(a, b) { return Math.sqrt(Math.pow(b.x - a.x, 2) + Math.pow(b.y - a.y, 2)) };
    this.vector.isSame = function(a, b) { return u(b) ? a.x == b.x && a.y == b.y : !1 };
    this.vector.getAngle2Points = Ea;
    this.vector.newStaticBox = function(a, b, c, d) { return { x: a, y: b, w: a + c, h: b + d } };
    this.vector.newDynamicBoxRect = function(a, b, c, d) {
        return [e(a, b), e(a +
            c, b), e(a + c, b + d), e(a, b + d)]
    };
    this.vector.moveCollision = function(a, b, c, d, n, e) {
        a._MCPNT_ || (a._MCPNT_ = game.newBaseObject({ w: a.w, h: a.h, x: a.x, y: a.y }));
        var f = !1,
            h = !1,
            g = c.abs();
        a.moveTimeC(a._MCPNT_.getPositionC(), 2);
        for (var z = a._MCPNT_.getStaticBoxPosition(), m = b.length - 1, k, l, p, q; 0 <= m; m--) k = b[m], n && !k.isInCameraStatic() || e && a._MCPNT_.getDistanceC(k.getPositionC()) > e || !a._MCPNT_.isStaticIntersect(k.getStaticBox()) || (l = k.getStaticBoxPosition(), p = g.x + g.y + 1, q = g.y + g.x + 1, z.y < l.h - q && z.h > l.y + q && (z.w > l.x && z.w < l.x +
            p && 0 < c.x ? (a._MCPNT_.x = l.x - a.w, c.x = 0, f = !0) : z.x < l.w && z.x > l.w - p && 0 > c.x && (a._MCPNT_.x = l.w, c.x = 0, f = !0)), z.x < l.w - p && z.w > l.x + p && (z.h > l.y && z.h < l.y + q && 0 < c.y ? (a._MCPNT_.y = l.y - a.h, c.y = 0, h = !0) : z.y < l.h && z.y > l.h - q && 0 > c.y && (a._MCPNT_.y = l.h, c.y = 0, h = !0)), d && d(a, k, f, h));
        a._MCPNT_.move(c)
    };
    this.vector.oldMoveCollision = function(a, b, c, d, n, f) {
        for (var h = e(c.x, c.y), g = 0, z = b.length, l; g < z; g += 1)
            if (l = b[g], !n || l.isInCameraStatic())
                if (!f || !a.getDistanceC(l.getPositionC())) {
                    var k = l.getStaticBox();
                    if (a.isIntersect(l)) {
                        var m = a.getStaticBox(),
                            p = Math.abs(c.x),
                            q = Math.abs(c.y);
                        m.x + m.w > k.x + 10 + p && m.x < k.x + k.w - 10 - p && (0 < c.y && m.y + m.h < k.y + k.h / 2 + q ? h.y = 0 : 0 > c.y && m.y > k.y + k.h - k.h / 2 - q && (h.y = 0));
                        m.y + m.h > k.y + 10 + q && m.y < k.y + k.h - 10 - q && (0 < c.x && m.x + m.w < k.x + k.w / 2 + p ? h.x = 0 : 0 > c.x && m.x > k.x + k.w - k.w / 2 - p && (h.x = 0));
                        d && d(a, l)
                    }
                } a.move(h);
        return h
    };
    this.vector.moveCollisionAngle = function(a, b, c, d, n, f, h) {
        var g = e();
        n = math.a2r(OOP.isDef(n) ? n : a.angle);
        g.x = c * Math.cos(n);
        g.y = c * Math.sin(n);
        c = 0;
        n = b.length;
        for (var z; c < n; c += 1)
            if (z = b[c], !f || z.isInCamera())
                if (!h || !a.getDistanceC(z.getPositionC())) {
                    var k =
                        z.getStaticBox();
                    if (a.isIntersect(z)) { var l = a.getStaticBox(),
                            m = Math.abs(g.x),
                            p = Math.abs(g.y);
                        l.x + l.w > k.x + 10 + m && l.x < k.x + k.w - 10 - m && (0 < g.y && l.y + l.h < k.y + k.h / 2 + p ? g.y = 0 : 0 > g.y && l.y > k.y + k.h - k.h / 2 - p && (g.y = 0));
                        l.y + l.h > k.y + 10 + p && l.y < k.y + k.h - 10 - p && (0 < g.x && l.x + l.w < k.x + k.w / 2 + m ? g.x = 0 : 0 > g.x && l.x > k.x + k.w - k.w / 2 - m && (g.x = 0));
                        d && d(a, z) }
                } a.move(g);
        return g
    };
    var Lb = {},
        pb = function() { var a = (new Date).getTime();
            Lb[a] && (a = pb());
            Lb[a] = !0; return a },
        x = function(a) { return Math.PI / 180 * a },
        ca = function(a, b, c) {
            var d = Math.floor(Math.random() *
                (b - a + 1) + a);
            return c && 0 == d ? ca(a, b, c) : d
        },
        qb = function(a) { return 0 > a ? -1 : 1 };
    this.math.limit = function(a, b) { var c = qb(a);
        a = Math.abs(a);
        b = Math.abs(b); return a < b ? a * c : b * c };
    this.math.sign = qb;
    this.math.a2r = x;
    this.math.random = ca;
    this.math.toInt = function(a) { return a >> 0 };
    this.math.uid = pb;
    this.math.toZiro = function(a, b) { if (0 == a) return 0; var c = qb(a);
        b = Math.abs(b);
        a = Math.abs(a); return 0 < a && (a -= b, a < b) ? 0 : a * c };
    var Mb = function(a, b) { return a ? a : b ? b : !1 },
        Nb = [],
        rc = function(a, b) {
            var c;
            this.canvas = c = g.document.createElement("canvas");
            var d = c.style,
                n = r.style;
            d.position = "fixed";
            d.top = n.top;
            d.left = n.left;
            c.width = r.width;
            c.height = r.height;
            d.width = n.width;
            d.height = n.height;
            d.zIndex = n.zIndex + a;
            b && (d.opacity = Mb(b.alpha, 1), d.backgroundColor = Mb(b.backgroundColor, "transparent"));
            m.attach(c);
            (this.context = c.getContext("2d")).textBaseline = t.textBaseline;
            this.isAutoClear = !0;
            this.clear = function() { this.context.clearRect(0, 0, l, p) };
            this.on = function(a) { h = this.context;
                this.isAutoClear && this.clear();
                a(this);
                h = Ob };
            this.setVisible = function(a) {
                this.canvas.style =
                    a ? "block" : "none"
            };
            Nb.push(this)
        },
        va = function() { v(Nb, function(a) { a.canvas.width = l;
                a.canvas.height = p;
                a.canvas.style.width = r.style.width;
                a.canvas.style.height = r.style.height;
                a.context.textBaseline = t.textBaseline }) };
    this.layers.newLayer = function(a, b) { return new rc(a, b) };
    var Pb = 0,
        m = {
            loaded: !1,
            events: { onload: [], preLoop: [], postLoop: [], gameBlur: [], gameFocus: [], gameResize: [] },
            addEvent: function(a, b, c) { "onload" == a && m.loaded ? c() : m.events[a].push({ id: b, func: c }) },
            delEvent: function(a, b) {
                v(m.events[a], function(a,
                    d, n) { a.id == b && n.splice(d, 1) })
            },
            runEvent: function(a) { v(m.events[a], function(a) { "function" == typeof a.func && a.func() }) },
            attach: function(a) { var b = function() { g.document.body.appendChild(a) };
                m.loaded ? b() : m.addEvent("onload", "attachElement_PointJS" + (Pb += 1), b) },
            remove: function(a) { var b = function() { g.document.body.removeChild(a) };
                m.loaded ? b() : m.addEvent("onload", "attachElement_PointJS" + (Pb += 1), b) },
            getWH: function() {
                return {
                    w: parseInt(g.document.documentElement.clientWidth || g.innerWidth || g.document.body.clientWidth),
                    h: parseInt(g.document.documentElement.clientHeight || g.innerHeight || g.document.body.clientHeight)
                }
            }
        };
    this.system.delEvent = function(a, b) { m.delEvent(a, b) };
    this.system.addEvent = function(a, b, c) { m.addEvent(a, b, c) };
    this.system.removeDOM = function(a) { m.remove(a) };
    this.system.attachDOM = function(a) { m.attach(a) };
    this.system.newDOM = function(a, b) {
        var c = g.document.createElement(a);
        c.style.position = "fixed";
        c.style.left = 0;
        c.style.top = 0;
        c.style.zIndex = ma.style.zIndex + 1;
        c.style.border = "none";
        if (b) {
            var d = function(a) { a.stopPropagation() };
            c.addEventListener("touchstart", d, !1);
            c.addEventListener("touchend", d, !1);
            c.addEventListener("touchmove", d, !1);
            c.addEventListener("mousedown", d, !1);
            c.addEventListener("mousepress", d, !1);
            c.addEventListener("mouseup", d, !1);
            c.addEventListener("mousemove", d, !1);
            c.addEventListener("keypress", d, !1);
            c.addEventListener("keydown", d, !1);
            c.addEventListener("keyup", d, !1);
            c.addEventListener("click", d, !1);
            c.addEventListener("wheel", d, !1);
            c.addEventListener("mousewheel", d, !1);
            c.addEventListener("contextmenu", d,
                !1);
            c.addEventListener("selectstart", d, !1);
            c.addEventListener("dragstart", d, !1);
            c.addEventListener("DOMMouseScroll", d, !1)
        }
        m.attach(c);
        return c
    };
    var h = null,
        Ob = null;
    var r = g.document.createElement("canvas");
    Ob = h = r.getContext("2d");
    h.textBaseline = t.textBaseline;
    r.crossOrigin = "anonymous";
    r.width = parseInt(ea);
    r.height = parseInt(fa);
    r.style.position = "fixed";
    r.style.left = 0;
    r.style.top = 0;
    r.style.zIndex = 1E4;
    r.id = "PointJS-canvas_0";
    if ("object" == typeof nb)
        for (var rb in nb) rb.match(/margin|padding|position/) ||
            (r.style[rb] = nb[rb]);
    m.addEvent("onload", "Window_Hide_Scroll", function() { g.document.body.style.overflow = "hidden";
        sb = { x: parseInt(r.style.left), y: parseInt(r.style.top) } });
    var ma = g.document.createElement("div");
    (function() { var a = ma.style;
        a.position = "fixed";
        a.top = a.left = 0;
        a.width = a.height = "100%";
        a.zIndex = 2E4 })();
    m.attach(ma);
    var sb = e(0, 0);
    m.attach(r);
    this.system.setStyle = function(a) { if ("object" == typeof a)
            for (var b in a) r.style[b] = a[b] };
    this.system.getCanvas = function() { return r };
    this.system.getContext =
        function() { return h };
    this.system.resize = function(a, b) { l = a || ea;
        p = b || fa;
        O = l / 2;
        P = p / 2;
        r.width = l;
        r.height = p };
    this.system.initFullPage = function() { m.addEvent("gameResize", "PointJS_resizeGame", function() { l = m.getWH().w;
            p = m.getWH().h;
            O = l / 2;
            P = p / 2;
            r.width = l;
            r.height = p;
            h.textBaseline = t.textBaseline;
            va() });
        m.runEvent("gameResize", "PointJS_resizeGame") };
    var V = !1,
        sc = function() {
            V || (this.requestFullscreen ? (this.requestFullscreen(), V = !0) : this.mozRequestFullScreen ? (this.mozRequestFullScreen(), V = !0) : this.webkitRequestFullscreen &&
                (this.webkitRequestFullscreen(), V = !0), l = m.getWH().w, p = m.getWH().h, O = l / 2, P = p / 2, r.width = l, r.height = p, va())
        },
        tb = function(a) { V = Qb(g.document.fullscreenElement || g.document.mozFullScreenElement || g.document.webkitFullscreenElement) };
    g.document.addEventListener("webkitfullscreenchange", tb);
    g.document.addEventListener("mozfullscreenchange", tb);
    g.document.addEventListener("fullscreenchange", tb);
    this.system.initFullScreen = function() {
        V || (g.document.documentElement.onclick = sc, Fa || (m.addEvent("gameResize", "PointJS_initFullScreen",
            function() { l = m.getWH().w;
                p = m.getWH().h;
                O = l / 2;
                P = p / 2;
                r.width = l;
                r.height = p;
                h.textBaseline = t.textBaseline;
                va() }), m.runEvent("gameResize", "PointJS_initFullScreen")))
    };
    this.system.exitFullScreen = function() {
        V && (m.delEvent("gameResize", "PointJS_initFullScreen"), g.document.exitFullscreen ? (g.document.exitFullscreen(), V = !1) : g.document.mozCancelFullScreen ? (g.document.mozCancelFullScreen(), V = !1) : g.document.webkitExitFullscreen && (g.document.webkitExitFullscreen(), V = !1), l = ea, p = fa, O = l / 2, P = p / 2, r.width = l, r.height =
            p, va(), g.document.documentElement.onclick = function() {})
    };
    this.system.isFullScreen = function() { return V };
    this.system.exitFullPage = function() { m.delEvent("gameResize", "PointJS_resizeGame");
        l = ea;
        p = fa;
        O = l / 2;
        P = p / 2;
        r.width = l;
        r.height = p;
        va() };
    var X = !1,
        Fa = !1,
        Rb = ea,
        Sb = fa,
        Tb = !1;
    this.system.initFullScale = function(a) {
        Fa || (a && (Tb = !0), m.addEvent("gameResize", "PointJS_initFullScale", function() {
            var a = Rb,
                c = Sb,
                d = m.getWH();
            Tb ? (a = d.w, c = d.h) : d.w < d.h ? (c = d.w / l, a = d.w, c *= p) : d.h < d.w && (a = d.h / p, c = d.h, a *= l);
            Rb = a;
            Sb = c;
            X = {
                w: a / l,
                h: c / p
            };
            r.style.width = a + "px";
            r.style.height = c + "px";
            va()
        }), m.runEvent("gameResize", "PointJS_initFullScale"), Fa = !0)
    };
    this.system.exitFullScale = function() { Fa && (Fa = !1, m.delEvent("gameResize", "PointJS_initFullScale"), r.style.width = ea + "px", r.style.height = fa + "px") };
    this.system.getWH = function() { return m.getWH() };
    var F = !1;
    this.actionControl.initActionControl = function() { q.touchControl.isTouchSupported() && (F = !0, q.touchControl.initTouchControl());
        q.mouseControl.initMouseControl(); return this };
    this.actionControl.isPress =
        function() { return F ? q.touchControl.isPress() : q.mouseControl.isPress("LEFT") };
    this.actionControl.isDown = function() { return F ? q.touchControl.isDown() : q.mouseControl.isDown("LEFT") };
    this.actionControl.isUp = function() { return F ? q.touchControl.isUp() : q.mouseControl.isUp("LEFT") };
    this.actionControl.isInObject = function(a) { return F ? q.touchControl.isInObject(a) : q.mouseControl.isInObject(a) };
    this.actionControl.isInStatic = function(a) { return F ? q.touchControl.isInStatic(a) : q.mouseControl.isInStatic(a) };
    this.actionControl.isInDynamic =
        function(a) { return F ? q.touchControl.isInDynamic(a) : q.mouseControl.isInDynamic(a) };
    this.actionControl.isPeekObject = function(a) { return F ? q.touchControl.isPeekObject(a) : q.mouseControl.isPeekObject("LEFT", a) };
    this.actionControl.isPeekStatic = function(a) { return F ? q.touchControl.isPeekStatic(a) : q.mouseControl.isPeekStatic("LEFT", a) };
    this.actionControl.isPeekDynamic = function(a) { return F ? q.touchControl.isPeekDynamic(a) : q.mouseControl.isPeekDynamic("LEFT", a) };
    this.actionControl.getPosition = function(a) {
        return F ?
            q.touchControl.getPosition() : q.mouseControl.getPosition()
    };
    this.actionControl.getPositionS = function(a) { return F ? q.touchControl.getPositionS() : q.mouseControl.getPositionS() };
    this.actionControl.getMouse = function() { return q.mouseControl };
    this.actionControl.getTouch = function() { return F ? q.touchControl : !1 };
    this.actionControl.getActiveControl = function() { return F ? q.touchControl : q.mouseControl };
    this.actionControl.getActiveControlName = function() { return F ? "touchControl" : "mouseControl" };
    this.actionControl.getSpeed =
        function() { if (!F) return q.mouseControl.getSpeed() || q.touchControl.getSpeed() };
    var ub = !1,
        Pa = { LEFT: 37, RIGHT: 39, UP: 38, DOWN: 40, SPACE: 32, CTRL: 17, SHIFT: 16, ALT: 18, ESC: 27, ENTER: 13, MINUS: 189, PLUS: 187, CAPS_LOCK: 20, BACKSPACE: 8, TAB: 9, Q: 81, W: 87, E: 69, R: 82, T: 84, Y: 89, U: 85, I: 73, O: 79, P: 80, A: 65, S: 83, D: 68, F: 70, G: 71, H: 72, J: 74, K: 75, L: 76, Z: 90, X: 88, V: 86, B: 66, N: 78, M: 77, 0: 48, 1: 49, 2: 50, 3: 51, 4: 52, 5: 53, 6: 54, 7: 55, 8: 56, C: 67, 9: 57, F1: 112, F2: 113, F3: 114, F4: 115, F5: 116, F6: 117, F7: 118, F8: 119, F9: 120, F10: 121, F11: 122, F12: 123 },
        wa = {
            37: "LEFT",
            39: "RIGHT",
            38: "UP",
            40: "DOWN",
            32: "SPACE",
            17: "CTRL",
            16: "SHIFT",
            18: "ALT",
            27: "ESC",
            13: "ENTER",
            189: "MINUS",
            187: "PLUS",
            20: "CAPS_LOCK",
            8: "BACKSPACE",
            9: "TAB",
            81: "Q",
            87: "W",
            69: "E",
            82: "R",
            84: "T",
            89: "Y",
            85: "U",
            73: "I",
            79: "O",
            80: "P",
            65: "A",
            83: "S",
            68: "D",
            70: "F",
            71: "G",
            72: "H",
            74: "J",
            75: "K",
            76: "L",
            90: "Z",
            88: "X",
            86: "V",
            66: "B",
            78: "N",
            77: "M",
            48: "0",
            49: "1",
            50: "2",
            51: "3",
            52: "4",
            53: "5",
            54: "6",
            55: "7",
            56: "8",
            67: "C",
            57: "9",
            112: "F1",
            113: "F2",
            114: "F3",
            115: "F4",
            116: "F5",
            117: "F6",
            118: "F7",
            119: "F8",
            120: "F9",
            121: "F10",
            122: "F11",
            123: "F12"
        },
        tc = { 8: !0, 9: !0, 13: !0, 18: !0, 16: !0, 17: !0, 27: !0, 112: !0, 113: !0, 114: !0, 115: !0, 116: !0, 117: !0, 118: !0, 119: !0, 120: !0, 121: !0, 122: !0, 123: !0 };
    this.keyControl.getKeyList = function() { var a, b = []; for (a in Pa) b.push(a); return b };
    var Y = {},
        Ga = {},
        na = {},
        Ha = !1,
        Ia = !1,
        Qa = !1,
        Ra = !1,
        uc = function(a) { D(na, function(a, c, d) { 1 == a && (d[c] = 2) }) };
    this.keyControl.getCountKeysDown = function() { var a = 0;
        D(Y, function(b, c) { b && a++ }); return a };
    this.keyControl.getAllKeysDown = function() { var a = [];
        D(Y, function(b, c) { b && a.push(wa[c]) }); return a };
    this.keyControl.getLastKeyPress = function() { return Ra ? wa[Ra] : !1 };
    this.keyControl.isDown = function(a) { return 1 == Y[Pa[a]] };
    this.keyControl.isUp = function(a) { return 1 == Ga[Pa[a]] };
    this.keyControl.isPress = function(a) { return 1 == na[Pa[a]] };
    this.keyControl.getInputChar = function() { return Ha };
    this.keyControl.getInputKey = function() { return wa[Ia] };
    this.keyControl.setInputMode = function(a) { Qa = a };
    this.keyControl.isInputMode = function() { return Qa };
    this.keyControl.exitKeyControl = function() {
        g.onkeydown = function() {};
        g.onkeypress =
            function() {};
        g.onkeyup = function() {};
        y.clear("key:down");
        y.clear("key:press");
        y.clear("key:up");
        m.delEvent("postLoop", "PointJS_clearAllKeyUp");
        m.delEvent("preLoop", "PointJS_KeyDownEvent");
        Y = {};
        Ga = {};
        na = {};
        ub = Qa = Ia = Ha = !1
    };
    this.keyControl.initControl = this.keyControl.initKeyControl = function() {
        if (ub) return this;
        ub = !0;
        g.onkeydown = function(a) {
            if (Qa) return Ia = a.keyCode, tc[a.keyCode] ? (a.preventDefault(), !1) : !0;
            a.preventDefault();
            2 != na[a.keyCode] && (na[a.keyCode] = 1, Ra = a.keyCode, y.run("key:press", wa[a.keyCode]));
            Y[a.keyCode] = !0;
            return !1
        };
        g.onkeypress = function(a) { var b = !1;
            0 != a.which && 0 != a.charCode && 32 <= a.which && (b = String.fromCharCode(a.which));
            Ha = b };
        g.onkeyup = function(a) { a.preventDefault();
            1 == Y[a.keyCode] && (Ga[a.keyCode] = !0);
            Y[a.keyCode] = !1;
            y.run("key:up", wa[a.keyCode]);
            delete na[a.keyCode];
            delete Y[a.keyCode]; return !1 };
        m.addEvent("postLoop", "PointJS_clearAllKeyUp", function() { Ga = {};
            uc();
            Ra = Ia = Ha = !1 });
        m.addEvent("preLoop", "PointJS_KeyDownEvent", function() {
            y.isEvent("key:down") && D(Y, function(a, b) {
                a && y.run("key:down",
                    wa[b])
            })
        });
        return this
    };
    var vb = !1,
        G = e(0, 0),
        Sa = e(0, 0);
    e(0, 0);
    var Ja = !0,
        Ta = "",
        Ua = !1,
        oa = e(0, 0),
        Va = !1,
        wb = { LEFT: 1, RIGHT: 3, MIDDLE: 2 },
        xb = { 1: "LEFT", 3: "RIGHT", 2: "MIDDLE" },
        Wa = !1,
        Xa = {},
        Ya = {},
        Ka = {},
        xa = 0,
        Ub = function() { Xa = {};
            Ya = {};
            Ka = {};
            xa = 0;
            Va = !1 },
        vc = function() { D(Ka, function(a, b, c) { 1 == a && (c[b] = 2) }) },
        Za = function(a) { var b = 0,
                c = 0;
            a && (b = f.x, c = f.y); return e(b + G.x, c + G.y) };
    this.mouseControl.getPosition = function() { return Za(1) };
    this.mouseControl.getPositionS = function() { return Za() };
    this.mouseControl.setCursorImage = function(a) {
        a =
            "url('" + a + "'), auto";
        Ta != a && (Ta = a, g.document.body.style.cursor = Ta)
    };
    this.mouseControl.setVisible = function(a) {!Ja && !a || Ja && a || (Ja = 1 == a, g.document.body.style.cursor = Ja ? Ta : "none") };
    this.mouseControl.isVisible = function() { return Ja };
    this.mouseControl.isDown = function(a) { return Xa[wb[a]] };
    this.mouseControl.isUp = function(a) { return Ya[wb[a]] };
    this.mouseControl.isPress = function(a) { return 1 == Ka[wb[a]] };
    this.mouseControl.isMove = function() { return Va };
    this.mouseControl.isInStatic = function(a) {
        var b = Za(1);
        return b.x >=
            a.x && b.x <= a.x + a.w && b.y >= a.y && b.y <= a.y + a.h
    };
    this.mouseControl.isInDynamic = function(a) { return la(Za(1), a) };
    this.mouseControl.isInObject = function(a) { return a.visible ? a.angle ? this.isInDynamic(a.getDynamicBox()) : this.isInStatic(a.getStaticBox()) : !1 };
    this.mouseControl.isWheel = function(a) { return "UP" == a && 0 < xa || "DOWN" == a && 0 > xa };
    var Vb = function(a) { a.preventDefault();
            xa = a.wheelDelta ? a.wheelDelta : -a.detail;
            y.run("mouse:wheel", 0 > xa ? "DOWN" : "UP"); return !1 },
        $a = !1,
        Wb = function() {
            $a && (Ua = u(g.document.pointerLockElement) ||
                u(g.document.mozPointerLockElement) ? !0 : !1)
        };
    this.mouseControl.initMouseLock = function() {
        m.addEvent("onload", "initPointerLock", function() {
            $a = ma.requestPointerLock || ma.mozRequestPointerLock || !1;
            g.document.exitPointerLock = g.document.exitPointerLock || g.document.mozExitPointerLock || !1;
            "onpointerlockchange" in g.document ? g.document.addEventListener("pointerlockchange", Wb, !1) : "onmozpointerlockchange" in g.document && g.document.addEventListener("mozpointerlockchange", Wb, !1);
            if (!$a) return U("error in initMouseLock : not supported");
            Ua || (ma.onclick = $a)
        })
    };
    this.mouseControl.exitMouseLock = function() { g.document.exitPointerLock();
        ma.onclick = function() {};
        oa = e(0, 0) };
    this.mouseControl.unlockMouse = function() { oa = e(0, 0);
        g.document.exitPointerLock() };
    this.mouseControl.isMouseLock = function() { return Ua };
    this.mouseControl.getSpeed = function() { return e(oa.x, oa.y) };
    this.mouseControl.isPeekStatic = function(a, b) { return this.isPress(a) ? this.isInStatic(b) : !1 };
    this.mouseControl.isPeekDynamic = function(a, b) {
        return this.isPress(a) ? this.isInDynamic(b) :
            !1
    };
    this.mouseControl.isPeekObject = function(a, b) { return this.isPress(a) && b.visible ? this.isInDynamic(b.getDynamicBox()) : !1 };
    this.mouseControl.initControl = this.mouseControl.initMouseControl = function() {
        if (vb) return this;
        vb = !0;
        g.onmousemove = function(a) {
            a.preventDefault();
            a.stopPropagation();
            if (Ua) { var b = a.movementY || a.mozMovementY || 0;
                G.x += a.movementX || a.mozMovementX || 0;
                G.y += b } else G.x = a.pageX - sb.x, G.y = a.pageY - sb.y, X && (G.x /= X.w, G.y /= X.h);
            oa.x = G.x - Sa.x;
            oa.y = G.y - Sa.y;
            Sa.x = G.x;
            Sa.y = G.y;
            y.run("mouse:move");
            Va = !0;
            return !1
        };
        g.onmousedown = function(a) { a.preventDefault();
            a.stopPropagation();!a.which && a.button && (a.button & 1 ? a.which = 1 : a.button & 4 ? a.which = 2 : a.button & 2 && (a.which = 3));
            y.run("mouse:press", xb[a.which]);
            Wa = xb[a.which];
            Xa[a.which] = !0;
            Ka[a.which] = 1 };
        g.onmouseup = function(a) { a.preventDefault();
            a.stopPropagation();!a.which && a.button && (a.button & 1 ? a.which = 1 : a.button & 4 ? a.which = 2 : a.button & 2 && (a.which = 3));
            y.run("mouse:up", xb[a.which]);
            Wa = !1;
            Xa[a.which] = !1;
            Ya[a.which] = !0;
            delete Ka[a.which] };
        g.oncontextmenu = g.onselectstart =
            g.ondragstart = function() { return !1 };
        g.onmousewheel = Vb;
        g.addEventListener("DOMMouseScroll", Vb, !1);
        m.addEvent("preLoop", "PointJS_MouseEventDown", function() { Wa && y.run("mouse:down", Wa) });
        m.addEvent("postLoop", "PointJS_clearAllMouseUp", function() { Ya = {};
            vc();
            xa = 0;
            Va = !1;
            oa = e(0, 0) });
        return this
    };
    this.mouseControl.exitMouseControl = function() {
        y.clear("mouse:press");
        y.clear("mouse:down");
        y.clear("mouse:up");
        y.clear("mouse:move");
        y.clear("mouse:wheel");
        g.onmousemove = g.onmousedown = g.onmouseup = g.oncontextmenu = g.onselectstart =
            g.ondragstart = g.onmousewheel = function() {};
        m.delEvent("postLoop", "PointJS_clearAllMouseUp");
        m.delEvent("preLoop", "PointJS_MouseEventDown");
        Ub();
        vb = !1
    };
    var yb = !1,
        La = !1,
        ab = 0,
        bb = 0,
        I = 0,
        J = 0,
        w = e(0, 0),
        cb = [],
        Ma = e(0, 0),
        db = e(0, 0);
    this.touchControl.isTouchSupported = function() { return !!("ontouchstart" in window) };
    this.touchControl.isMobileDevice = function() { return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(g.navigator.userAgent) };
    var Xb = function() { La = !1;
        bb = ab = 0;
        w = e(0, 0);
        cb = [];
        J = I = 0 };
    this.touchControl.getFixPositionS =
        function() { return w.x || w.y ? e(w.x, w.y) : !1 };
    this.touchControl.getFixPosition = function() { return w.x || w.y ? e(w.x + f.x, w.y + f.y) : !1 };
    this.touchControl.getRun = function() { var a = 0,
            b = 0;
        w.x && w.x != I && (a = I - w.x);
        w.y && w.y != J && (b = J - w.y); return e(a, b) };
    this.touchControl.getVector = function() { var a = 0,
            b = 0;
        w.x && w.x != I && (a = I > w.x ? 1 : -1);
        w.y && w.y != J && (b = J > w.y ? 1 : -1); return e(a, b) };
    this.touchControl.getSpeed = function() { return e(Ma.x, Ma.y) };
    this.touchControl.isDown = function() { return La };
    this.touchControl.isPress = function() {
        return 1 ==
            ab
    };
    this.touchControl.isUp = function() { return 1 == bb };
    this.touchControl.getPosition = function() { return e(I + f.x, J + f.y) };
    this.touchControl.getPositionS = function() { return e(I, J) };
    this.touchControl.isPeekStatic = function(a) { return this.isPress() ? this.isInStatic(a) : !1 };
    this.touchControl.isPeekDynamic = function(a) { return this.isPress() ? this.isInDynamic(a) : !1 };
    this.touchControl.isPeekObject = function(a) { return this.isPress() && a.visible ? this.isInDynamic(a.getDynamicBox()) : !1 };
    this.touchControl.isInStatic = function(a) {
        var b =
            this.getPosition();
        return b.x >= a.x && b.x <= a.x + a.w && b.y >= a.y && b.y <= a.y + a.h
    };
    this.touchControl.isInDynamic = function(a) { return la(this.getPosition(), a) };
    this.touchControl.isInObject = function(a) { return a.visible ? a.angle ? this.isInDynamic(a.getDynamicBox()) : this.isInStatic(a.getStaticBox()) : !1 };
    this.touchControl.getTouches = function() { return cb };
    this.touchControl.initControl = this.touchControl.initTouchControl = function() {
        if (yb) return this;
        yb = !0;
        g.addEventListener("touchstart", function(a) {
            a.preventDefault();
            I = a.targetTouches[0].pageX;
            J = a.targetTouches[0].pageY;
            cb = a.targetTouches;
            X && (I /= X.w, J /= X.h);
            y.run("touch:press");
            w.x = I;
            w.y = J;
            La = !0;
            ab = 1;
            return !1
        }, { passive: !1 });
        g.addEventListener("touchmove", function(a) { I = a.targetTouches[0].pageX;
            J = a.targetTouches[0].pageY;
            cb = a.targetTouches;
            X && (I /= X.w, J /= X.h);
            Ma.x = I - db.x;
            Ma.y = J - db.y;
            y.run("touch:move"); return !1 }, !1);
        g.addEventListener("touchend", function(a) { w.x = 0;
            w.y = 0;
            La = !1;
            bb = 1;
            y.run("touch:up"); return !1 }, !1);
        q.touchControl.vibrate = function(a) {
            if (g.navigator.vibrate) return g.navigator.vibrate(a);
            if (g.navigator.oVibrate) return g.navigator.oVibrate(a);
            if (g.navigator.mozVibrate) return g.navigator.mozVibrate(a);
            if (g.navigator.webkitVibrate) return g.navigator.webkitVibrate(a)
        };
        m.addEvent("preLoop", "PointJS_TouchDownEvent", function() { La && y.run("touch:down") });
        m.addEvent("postLoop", "PointJS_touchStopPress", function() { bb = ab = 0;
            db.x = I;
            db.y = J;
            Ma = e(0, 0) });
        return this
    };
    this.touchControl.exitTouchControl = function() {
        g.ontouchstart = g.ontouchmove = g.ontouchend = function(a) {};
        m.delEvent("postLoop", "PointJS_touchStopPress");
        m.delEvent("preLoop", "PointJS_TouchDownEvent");
        Xb();
        yb = !1
    };
    var eb = function(a, b, c, d) { return d ? "rgba(" + a + ", " + b + ", " + c + ", " + d + ")" : "rgb(" + a + ", " + b + ", " + c + ")" },
        Yb = function(a, b) { a = "#" == a[0] ? a.substr(1, 6) : a; var c = parseInt(a.substr(0, 2), 16),
                d = parseInt(a.substr(2, 2), 16),
                n = parseInt(a.substr(4, 2), 16); return eb(c, d, n, b) };
    this.colors.rgb = function(a, b, c) { return eb(a, b, c) };
    this.colors.rgba = function(a, b, c, d) { return eb(a, b, c, d) };
    this.colors.hex2rgb = function(a) { return Yb(a) };
    this.colors.hex2rgba = function(a, b) {
        return Yb(a,
            b)
    };
    this.colors.randomColor = function(a, b, c) { return eb(ca(a, b), ca(a, b), ca(a, b), c || 1) };
    var u = function(a) { return "undefined" == typeof a || null == a ? !1 : !0 },
        Qb = function(a) { return u(a) && "" !== a && 0 !== a ? !0 : !1 },
        D = function(a, b) { var c, d; for (c in a)
                if ("undefined" != typeof a[c] && (d = b(a[c], c, a)) && "break" == d) break },
        v = function(a, b) { if (a.length)
                for (var c = a.length - 1, d; 0 <= c && ("undefined" === typeof a[c] || !(d = b(a[c], c, a) || !1) || "break" !== d); c--); };
    this.OOP.extractArrElement = function(a, b) { var c = a[b];
        a.splice(b, 1); return c };
    this.OOP.extractRandArrElement =
        function(a) { var b = ca(0, a.length - 1),
                c = a[b];
            a.splice(b, 1); return c };
    this.OOP.drawEach = function(a, b) { D(a, function(a) { a && a.draw && a.isInCamera() && (a.draw(), b && b(a)) }) };
    this.OOP.drawArr = function(a, b) { var c; var d = 0; for (c = a.length; d < c; d += 1) a[d] && a[d].draw && a[d].isInCamera() && (a[d].draw(), b && b(a[d], d)) };
    var Zb = function(a) { a.length = 0 },
        wc = function(a, b) {
            var c = !1,
                d = pb(),
                n = !1,
                e = new XMLHttpRequest,
                f = function() { e.open("GET", a, !0);
                    e.send() };
            e.onreadystatechange = function() {
                4 == e.readyState && (b(e.responseText), c && (n ?
                    setTimeout(f, n) : f()))
            };
            this.start = function() { a = a.match(/\?/) ? a + ("&session_id=" + d) : a + ("?session_id=" + d);
                f();
                c = !0 };
            this.setSID = function(a) { d = a };
            this.setTime = function(a) { n = a };
            this.stop = function() { c = !1 };
            this.isActive = function() { return c }
        };
    this.OOP.readJSON = function(a, b) { var c = {},
            d = new XMLHttpRequest;
        d.open("GET", a, !0);
        A.add();
        d.onreadystatechange = function() { 4 == d.readyState && (c = d.responseText, c = JSON.parse(c), A.load(), b(c)) };
        d.send() };
    this.OOP.toString = function(a, b) {
        var c, d = 0,
            n = "[";
        for (c in a)
            if (a.hasOwnProperty(c)) {
                var e =
                    a[c];
                "number" == typeof e && b && (e = parseInt(e));
                n += (0 < d ? ", " : "") + c + " : " + e;
                d += 1
            } return n + "]"
    };
    this.OOP.sendGET = function(a, b, c) { var d = new XMLHttpRequest,
            n = "?";
        D(b, function(a, b) { n += b + "=" + encodeURIComponent(a) + "&" });
        d.open("GET", a + n, !0);
        d.onreadystatechange = function() { 4 == d.readyState && c(d.responseText) };
        d.send() };
    this.OOP.sendPOST = function(a, b, c) {
        var d = new XMLHttpRequest,
            n = "";
        D(b, function(a, b) { n += b + "=" + encodeURIComponent(a) + "&" });
        d.open("POST", a, !0);
        d.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        d.onreadystatechange = function() { 4 == d.readyState && c(d.responseText) };
        d.send(n)
    };
    this.OOP.sendPOSTScreen = function(a, b, c) { var d = new XMLHttpRequest;
        b = b + "=" + r.toDataURL("image/png");
        d.open("POST", a, !0);
        d.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        d.onreadystatechange = function() { 4 == d.readyState && c(d.responseText) };
        d.send(b) };
    this.OOP.isDef = u;
    this.OOP.isSet = Qb;
    this.OOP.forEach = D;
    this.OOP.forInt = function(a, b) { var c, d; for (c = 0; c < a && (!(d = b(c)) || "break" != d); c += 1); };
    this.OOP.forXY = function(a,
        b, c) { var d, n, e; for (n = 0; n < b; n += 1)
            for (d = 0; d < a && (!(e = c(d, n)) || "break" != e); d += 1); };
    this.OOP.forArr = v;
    this.OOP.clearArr = Zb;
    this.OOP.fillArr = function(a, b, c) { a.length = 0; var d; for (d = 0; d < b; d += 1) a.push(c(d, 0 < d ? a[d - 1] : !1)); return a };
    this.OOP.delObject = function(a, b) { var c; var d = 0; for (c = a.length; d < c; d += 1)
            if (a[d] == b) return a.splice(d, 1), !0 };
    this.OOP.randArrElement = function(a) { return a[ca(0, a.length - 1)] };
    this.OOP.readJSONSync = function(a) {
        var b = new XMLHttpRequest;
        b.open("GET", a, !1);
        b.send();
        a = b.responseText;
        return a =
            JSON.parse(a)
    };
    this.OOP.sendGETSync = function(a, b) { var c = new XMLHttpRequest,
            d = "?";
        D(b, function(a, b) { d += b + "=" + encodeURIComponent(a) + "&" });
        c.open("GET", a + d, !1);
        c.send(); return c.responseText };
    this.OOP.sendPOSTSync = function(a, b) { var c = new XMLHttpRequest,
            d = "";
        D(b, function(a, b) { d += b + "=" + encodeURIComponent(a) + "&" });
        c.open("POST", a, !1);
        c.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        c.send(d); return c.responseText };
    this.OOP.newAJAXListener = function(a, b) { return new wc(a, b) };
    this.OOP.runCode =
        function(a) {
            (new Function("", a))() };
    var K = {};
    this.OOP.includeSync = function(a, b) { if (K[a]) K[a].loaded && !b && K[a].code();
        else { K[a] = { loaded: !1, code: function() { console.log(a + " is loading") } }; var c = new XMLHttpRequest;
            c.open("GET", a, !1);
            c.send();
            K[a].code = new Function("", c.responseText);
            K[a].loaded = !0;
            K[a].code() } };
    this.OOP.include = function(a, b, c) {
        if (K[a]) K[a].loaded && !c && K[a].code(), b && b();
        else {
            K[a] = { loaded: !1, code: function() { console.log(a + " is loading") } };
            var d = new XMLHttpRequest;
            d.open("GET", a, !0);
            d.onreadystatechange =
                function() { 4 == d.readyState && (K[a].code = new Function("", d.responseText), K[a].loaded = !0, K[a].code(), b && b()) };
            d.send()
        }
    };
    this.OOP.clone = function(a, b) { var c = $b(a);
        D(a, function(a, b) {-1 === ["id", "type"].indexOf(b) && (c[b] = a) });
        b && (c.onClone = b, c.onClone(c), delete c.onClone); return c };
    var xc = function() {
        var a = [];
        this.fillFromArr = function(b) { a.length = 0;
            v(b, function(b) { a.push(b) }) };
        this.fill = function(b, c) { a.length = 0;
            q.OOP.fillArr(a, b, c) };
        this.draw = function(b) {
            for (var c = a.length - 1; 0 <= c; c--) a[c].isInCamera() && (a[c].draw(),
                b && b(a[c], c))
        };
        this.update = function(b, c) { for (var d = a.length - 1; 0 <= d; d--) c && !a[d].isInCamera() || b(a[d], d) };
        this.add = function(b) { a.push(b) };
        this.del = function(b) { q.OOP.delObject(a, b) }
    };
    this.OOP.newGroup = function() { return new xc };
    var ya = 60,
        L = Date.now(),
        fb = 0,
        gb = -1,
        ac = L,
        ia = {},
        hb = 0;
    this.game.setFPS = function(a) { ya = 0 < a ? a : 60 };
    this.game.getFPS = function() { return ya };
    this.game.getDT = function(a) { a || (a = 1E3); return fb / a };
    this.game.getTime = function() { return L };
    var bc = function() {
            return g.requestAnimationFrame || g.webkitRequestAnimationFrame ||
                g.mozRequestAnimationFrame || g.oRequestAnimationFrame || g.msRequestAnimationFrame || function(a) { g.setTimeout(a, 1E3 / ya) }
        },
        za = bc(),
        cc = function() { L = Date.now();
            Kb && h.clearRect(0, 0, l, p);
            m.runEvent("preLoop") },
        dc = function() { m.runEvent("postLoop"); - 1 != gb && (fb = L - gb);
            gb = L },
        M = { func: function() { console.log('please, use a "setLoop" function.');
                za = function() {} }, events: !1, start: !1, end: !1, audio: !1, fps: !1, name: "NotLoop" },
        ec = function() { M.audio && v(M.audio, function(a) { a.stop() }) };
    this.game.newLoop = function(a, b, c, d, n) {
        "function" ==
        typeof b ? ia[a] = { events: n || !1, func: b, start: c || !1, end: d || !1, audio: !1, fps: !1, name: a } : ja("error in newLoop : " + b + " is not a function")
    };
    this.game.newLoopFromClassObject = function(a, b) { if (!b.update) return ja('error in newLoopFromClassObject : function "update" not found');
        ia[a] = { events: b.events || !1, func: b.update, start: b.entry || !1, end: b.exit || !1, audio: !1, fps: !1, name: a } };
    this.game.newLoopFromConstructor = function(a, b) { q.game.newLoopFromClassObject(a, new b) };
    this.game.setLoopSound = function(a, b) {
        var c;
        ia[a].audio ||
            (ia[a].audio = []);
        for (c = 0; c < b.length; c += 1) ia[a].audio.length = 0, b[c].setNextPlay(b[c + 1 == b.length ? 0 : c + 1]), ia[a].audio.push(b[c])
    };
    this.game.setLoop = function(a) { if (!ia[a]) return ja("setLoop : " + a + " is no a Loop");
        ec();
        Ub();
        Y = {};
        Ga = {};
        na = {};
        Ia = Ha = !1;
        Xb();
        zb(e(0, 0));
        M.end && M.end();
        M = ia[a];
        y.loadFromEvents(M.events);
        M.start && M.start();
        M.audio && M.audio[0].play() };
    var y = new function() {
        var a = { "mouse:click": [] },
            b = this;
        this.add = function(b, d) { a[b] || (a[b] = []);
            a[b].push(d) };
        this.run = function(b, d) { a[b] && v(a[b], function(a) { return a(d) }) };
        this.clear = function(b) { a[b] && (a[b].length = 0) };
        this.clearAll = function() { D(a, function(a) { a.length = 0 }) };
        this.loadFromEvents = function(a) { b.clearAll();
            a && D(a, function(a, c) { b.add(c, a) }) };
        this.isEvent = function(b) { return !!a[b] }
    };
    this.game.tick = function(a, b) { hb == a && b() };
    var ib = {};
    this.game.skip = function(a, b, c) { u(ib[a]) || (ib[a] = 0);
        ib[a]++ >= b && (c(), ib[a] = 0) };
    var Ab = function() {
            60 > hb ? hb++ : hb = 0;
            if (60 > ya) {
                var a = 1E3 / ya;
                try { L = Date.now(), L - ac > a && (cc(), M.func(fb), ac = L, dc()) } catch (b) { Ca && Oa(b), ob && (Ca || Oa(b), ja()) } za(Ab);
                return !1
            }
            try { cc(), M.func(fb), dc() } catch (b) { Ca && Oa(b), ob && (Ca || Oa(b), ja()) } za(Ab)
        },
        fc = function(a) { ka || (ka = !0, ya = a || 60, za(Ab)) },
        ja = function(a) { if (!ka) return U(u(a) ? a : "game is stop");
            ka = !1;
            ec();
            za = function() { U(u(a) ? a : "game is stop") } };
    this.game.getWH = function() { return { w: l, h: p, w2: O, h2: P } };
    this.game.getWH2 = function() { return { w: l / 2, h: p / 2 } };
    this.game.getResolution = function() { return Math.min(l / ea, p / fa) };
    this.game.startLoop = function(a, b) { this.setLoop(a);
        this.start(b) };
    this.game.start = fc;
    this.game.stop = ja;
    this.game.resume =
        function(a) { if (!ka) return M.audio && M.audio[0].play(), U(a || "game is run"), za = bc(), gb = -1, fc(), !1 };
    var yc = [],
        zc = 0,
        B = function(a) {
            this.type = "BaseObject";
            this.id = zc += 1;
            this.x = a.x || 0;
            this.y = a.y || 0;
            this.w = a.w || 0;
            this.h = a.h || 0;
            this.ondraw = a.ondraw ? a.ondraw : !1;
            this.parent = !1;
            this.children = [];
            this.fillColor = a.fillColor || !1;
            this.strokeColor = a.strokeColor || t.strokeStyle;
            this.strokeWidth = a.strokeWidth || 0;
            this.angle = a.angle || 0;
            this.alpha = u(a.alpha) ? a.alpha : 1;
            this.center = e(0, 0);
            this.box = { x: 0, y: 0, w: 0, h: 0 };
            this.visible =
                u(a.visible) ? a.visible : !0;
            this.flip = e(0, 0);
            this.setShadow(a);
            a.userData && this.setUserData(a.userData);
            a.center && this.setCenter(a.center);
            a.box && this.setBox(a.box);
            a.size && this.setSize(a.size);
            a.sizeC && this.setSizeC(a.sizeC);
            a.position && this.setPosition(a.position);
            a.positionC && this.setPositionC(a.positionC);
            "function" == typeof a.oncreate && (this.oncreate = a.oncreate, this.oncreate(), delete this.oncreate);
            yc.push(this)
        };
    B.prototype = {
        getID: function() { return this.id },
        getType: function() { return this.type },
        getParent: function() { return this.parent },
        addChild: function(a) { a && a.id != this.id && (a.parent = this, this.children.push(a), a.move(this.getPosition()), a.setPositionC(E(a.getPositionC(), this.getPositionC(), this.angle)), a.turn(this.angle)) },
        delChild: function(a) { a.parent = !1; var b; var c = 0; for (b = this.children.length; c < b; c += 1)
                if (this.children[c].id == a.id) { this.children.splice(c, 1); break } },
        delParent: function() { this.parent.delChild(this) },
        setBox: function(a) {
            a.offset && (this.box.x = a.offset.x || 0, this.box.y = a.offset.y ||
                0);
            a.size && (this.box.w = a.size.w || 0, this.box.h = a.size.h || 0)
        },
        isArrIntersect: function(a) { var b; var c = 0; for (b = a.length; c < b; c += 1)
                if (a[c].id != this.id && this.isIntersect(a[c])) return a[c]; return !1 },
        isArrInside: function(a) { var b; var c = 0; for (b = a.length; c < b; c += 1)
                if (this.isDynamicInside(a[c].getDynamicBox())) return a[c]; return !1 },
        getNearest: function(a) {
            var b = 0,
                c = !1,
                d;
            var n = 0;
            for (d = a.length; n < d; n += 1)
                if (this.id != a[n].id) {
                    !1 === c && (c = this.getDistanceC(a[n].getPositionC()), b = n);
                    var e = this.getDistanceC(a[n].getPositionC());
                    e < c && (c = e, b = n)
                } return a[b]
        },
        setFlip: function(a, b) { u(a) && this.flip.x != a && (this.flip.x = a);
            u(b) && this.flip.y != b && (this.flip.y = b) },
        setUserData: function(a) { for (var b in a) u(this[b]) || (this[b] = a[b]) },
        setShadow: function(a) { this.shadowColor = a.shadowColor || !1;
            this.shadowBlur = u(a.shadowBlur) ? a.shadowBlur : 3;
            this.shadowX = a.shadowX || 0;
            this.shadowY = a.shadowY || 0 },
        getDynamicBox: function() {
            var a = this.getPosition(1);
            return 0 == this.angle ? [e(this.x + this.box.x, this.y + this.box.y), e(this.x + this.box.x + this.w + this.box.w,
                this.y + this.box.y), e(this.x + this.box.x + this.w + this.box.w, this.y + this.box.y + this.h + this.box.h), e(this.x + this.box.x, this.y + this.box.y + this.h + this.box.h)] : [E(e(this.x + this.box.x, this.y + this.box.y), a, this.getAngle()), E(e(this.x + this.box.x + this.w + this.box.w, this.y + this.box.y), a, this.getAngle()), E(e(this.x + this.box.x + this.w + this.box.w, this.y + this.box.y + this.h + this.box.h), a, this.getAngle()), E(e(this.x + this.box.x, this.y + this.box.y + this.h + this.box.h), a, this.getAngle())]
        },	
        isDynamicIntersect: function(a) {
            if (3 >
                a.length) return !1;
            var b = this.getDynamicBox(),
                c;
            var d = 0;
            for (c = b.length; d < c; d += 1)
                if (la(b[d], a)) return !0;
            d = 0;
            for (c = a.length; d < c; d += 1)
                if (la(a[d], b)) return !0;
            return !1
        },
        isIntersect: function(a) { return a.visible ? this.angle || a.angle ? this.isDynamicIntersect(a.getDynamicBox()) : this.isStaticIntersect(a.getStaticBox()) : !1 },
        isDynamicInside: function(a) { if (3 > a.length) return !1; var b = this.getDynamicBox(),
                c, d = 0; var e = 0; for (c = b.length; e < c; e += 1) la(b[e], a) && (d += 1); return d == b.length ? !0 : !1 },
        drawDynamicBox: function(a) {
            N(this,
                1);
            h.shadowColor = "transparent";
            Aa(e(this.x + this.box.x, this.y + this.box.y), C(this.w + this.box.w, this.h + this.box.h), !1, a || "yellow", 2);
            gc(e(this.x + this.w / 2 + this.center.x, this.y + this.h / 2 + this.center.y), 10, a || "yellow");
            H()
        },
        drawStaticBox: function(a) { h.shadowColor = "transparent";
            Aa(e(this.x + this.box.x, this.y + this.box.y), C(this.w + this.box.w, this.h + this.box.h), !1, a || "yellow", 2);
            gc(e(this.x + this.w / 2 + this.center.x, this.y + this.h / 2 + this.center.y), 10, a || "yellow") },
        isStaticIntersect: function(a) {
            return this.y + this.box.y +
                this.h + this.box.h >= a.y && this.x + this.box.x + this.w + this.box.w >= a.x && this.x + this.box.x < a.x + a.w && this.y + this.box.y < a.y + a.h
        },
        getStaticBoxPosition: function() { return { x: this.x + this.box.x, y: this.y + this.box.y, w: this.x + this.box.x + this.w + this.box.w, h: this.y + this.box.y + this.h + this.box.h } },
        getStaticBox: function() { return { x: this.x + this.box.x, y: this.y + this.box.y, w: this.w + this.box.w, h: this.h + this.box.h } },
        setAlpha: function(a) { this.alpha != a && (this.alpha = 0 <= a ? 1 >= a ? a : 1 : 0) },
        transparent: function(a) {
            this.setAlpha(this.alpha +
                a)
        },
        getAlpha: function() { return this.alpha },
        rotate: function(a) { this.setAngle(Math.atan2(a.y - this.getPosition(1).y, a.x - this.getPosition(1).x) * (180 / Math.PI)) },
        setCenter: function(a) { this.center = e(a.x, a.y) },
        nullCenter: function(a) { a || (a = e(0, 0));
            this.center = e(-this.w / 2 + a.x, -this.h / 2 + a.y) },
        getCenter: function() { return e(this.center.x, this.center.y) },
        getBox: function() { return this.box },
        move: function(a) { this.prevPosition = this.getPosition();
            this.x += a.x;
            this.y += a.y },
        circling: function(a, b, c) {
            u(this.circlingAnglePointJS) ||
                (this.circlingAnglePointJS = 0);
            this.x = a.x + b * Math.cos(x(this.circlingAnglePointJS));
            this.y = a.y + b * Math.sin(x(this.circlingAnglePointJS));
            this.circlingAnglePointJS = 360 < this.circlingAnglePointJS ? 0 : this.circlingAnglePointJS + c
        },
        circlingC: function(a, b, c) {
            u(this.circlingAnglePointJS) || (this.circlingAnglePointJS = 0);
            this.setPositionC(e(a.x + b * Math.cos(x(this.circlingAnglePointJS)), a.y + b * Math.sin(x(this.circlingAnglePointJS))));
            this.circlingAnglePointJS = 360 < this.circlingAnglePointJS ? 0 : this.circlingAnglePointJS +
                c
        },
        motion: function(a, b, c) {
        	u(this.motionPercentPointJS) || (this.motionPercentPointJS = 0);
            this.x = a.x + b.w * Math.cos(x(this.motionPercentPointJS));
            this.y = a.y + b.h * Math.sin(x(this.motionPercentPointJS));
            this.motionPercentPointJS = 360 < this.motionPercentPointJS ? 0 : this.motionPercentPointJS + c },
        motionC: function(a, b, c) {
            u(this.motionPercentPointJS) || (this.motionPercentPointJS = 0);
            this.setPositionC(e(a.x + b.w * Math.cos(x(this.motionPercentPointJS)), a.y + b.h * Math.sin(x(this.motionPercentPointJS))));
            this.motionPercentPointJS =
                360 < this.motionPercentPointJS ? 0 : this.motionPercentPointJS + c
        },
        scale: function(a) { this.w *= a;
            this.h *= a },
        scaleC: function(a) { var b = this.w,
                c = this.h;
            this.scale(a);
            this.move(e(-((this.w - b) / 2), -((this.h - c) / 2))) },
        getPosition: function(a) { return 1 == a ? e(this.x + (this.w / 2 + this.center.x), this.y + (this.h / 2 + this.center.y)) : 2 == a ? (a = e(this.x + this.w / 2, this.y + this.h / 2), this.angle && (a = E(a, this.getPosition(1), this.angle)), e(a.x, a.y)) : e(this.x, this.y) },
        getPositionC: function() {
            return e(this.x + (this.w / 2 + this.center.x), this.y +
                (this.h / 2 + this.center.y))
        },
        getPositionS: function() { return e(this.x + f.x, this.y + f.x) },
        getPositionCS: function() { return e(this.x + (this.w / 2 + this.center.x) + f.x, this.y + (this.h / 2 + this.center.y) + f.y) },
        setPosition: function(a) { this.getPosition();!1 !== a.x && (this.x = a.x);!1 !== a.y && (this.y = a.y) },
        setPositionS: function(a) { this.getPosition();!1 !== a.x && (this.x = a.x + f.x);!1 !== a.y && (this.y = a.y + f.y) },
        setPositionC: function(a) {
            this.getPosition();
            !1 !== a.x && (this.x = -(this.w / 2 + this.center.x) + a.x);
            !1 !== a.y && (this.y = -(this.h /
                2 + this.center.y) + a.y)
        },
        setPositionCS: function(a) { this.getPosition();!1 !== a.x && (this.x = -(this.w / 2 + this.center.x) + a.x + f.x);!1 !== a.y && (this.y = -(this.h / 2 + this.center.y) + a.y + f.y) },
        getSize: function() { return C(this.w, this.h) },
        setSize: function(a) { this.w = a.w;
            this.h = a.h },
        setSizeC: function(a) { this.w = a.w;
            this.h = a.h;
            this.move(e(-(a.w / 2), -(a.h / 2))) },
        turn: function(a) { this.angle += a },
        rotateForAngle: function(a, b) {
            0 > this.angle && (this.angle += 360);
            0 > a && (a += 360);
            var c = this.angle - a;
            180 < c ? c -= 360 : -180 > c && (c += 360);
            c >= -b - .5 &&
                c <= b + .5 ? this.angle = a : c > b + .5 ? this.angle -= b : c < -b - .5 && (this.angle += b)
        },
        rotateForPoint: function(a, b) { var c = Ea(this.getPositionC(), a);
            this.rotateForAngle(c, b) },
        rotateForObject: function(a, b) { var c = Ea(this.getPositionC(), a.getPositionC());
            this.rotateForAngle(c, b) },
        moveTo: function(a, b) { var c = x(Ea(this.getPosition(), a));
            this.prevPosition = this.getPosition();
            this.x += b * Math.cos(c);
            this.y += b * Math.sin(c) },
        moveToC: function(a, b) {
            var c = x(Ea(this.getPositionC(), a));
            this.prevPosition = this.getPosition();
            this.x += b * Math.cos(c);
            this.y += b * Math.sin(c)
        },
        moveAngle: function(a, b) { b = x(u(b) ? b : this.angle);
            this.prevPosition = this.getPosition();
            this.x += a * Math.cos(b);
            this.y += a * Math.sin(b) },
        moveTime: function(a, b) { b = b || 1; var c = this.getPosition();
            this.move(e((a.x - c.x) / b, (a.y - c.y) / b)) },
        moveTimeC: function(a, b) { b = b || 1; var c = this.getPosition(1);
            this.move(e((a.x - c.x) / b, (a.y - c.y) / b)) },
        getAngle: function() { return this.angle },
        setAngle: function(a) { this.angle != a && (this.angle = a % 360) },
        getDistance: function(a) {
            return Math.sqrt(Math.pow(a.x - this.getPosition(2).x,
                2) + Math.pow(a.y - this.getPosition(2).y, 2))
        },
        getDistanceC: function(a) { return Math.sqrt(Math.pow(a.x - this.getPosition(1).x, 2) + Math.pow(a.y - this.getPosition(1).y, 2)) },
        setVisible: function(a) { this.visible = 1 == a },
        isVisible: function() { return this.visible },
        isInCamera: function() { return this.angle ? this.isInCameraDynamic() : this.isInCameraStatic() },
        isInCameraStatic: function() { return this.x + this.w < f.x || this.x > f.x + l || this.y + this.h < f.y || this.y > f.y + p ? !1 : !0 },
        isInCameraDynamic: function() {
            var a = this.getDynamicBox(),
                b = [e(f.x, f.y), e(f.x + l, f.y), e(f.x + l, f.y + p), e(f.x, f.y + p)],
                c, d = 0;
            var n = 0;
            for (c = a.length; n < c; n += 1) la(a[n], b) && (d += 1);
            return 0 < d
        },
        draw: function() {}
    };
    this.game.newBaseObject = function(a) { return new B(a) };
    var jb = function(a) { B.call(this, a);
        this.type = "TriangleObject" };
    ba(B, jb);
    jb.prototype.getDynamicBox = function() {
        var a = this.getPositionC();
        return 0 == this.angle ? [e(this.x + this.w / 2, this.y), e(this.x + this.w, this.y + this.h), e(this.x, this.y + this.h)] : [E(e(this.x + this.w / 2, this.y), a, this.getAngle()), E(e(this.x + this.w, this.y +
            this.h), a, this.getAngle()), E(e(this.x, this.y + this.h), a, this.getAngle())]
    };
    jb.prototype.draw = function() { if (this.visible && this.alpha) { var a = !1; if (this.angle || 1 != this.alpha || this.shadowColor) N(this), a = !0;
            Na(this.x, this.y, [e(this.w / 2, 0), e(this.w, this.h), e(0, this.h)], this.fillColor, this.strokeWidth ? this.strokeColor : !1, this.strokeWidth); if (this.ondraw) this.ondraw();
            a && H() } };
    this.game.newTriangleObject = function(a) { return new jb(a) };
    var Bb = function(a) { B.call(this, a);
        this.type = "RectObject" };
    ba(B, Bb);
    Bb.prototype.draw =
        function() { if (this.visible && this.alpha) { var a = !1; if (this.angle || 1 != this.alpha || this.shadowColor) N(this), a = !0;
                Aa(e(this.x, this.y), C(this.w, this.h), this.fillColor, this.strokeColor, this.strokeWidth); if (this.ondraw) this.ondraw();
                a && H() } };
    this.game.newRectObject = function(a) { return new Bb(a) };
    var Cb = function(a) { B.call(this, a);
        this.type = "RoundRectObject";
        this.radius = a.radius || 1 };
    ba(B, Cb);
    Cb.prototype.draw = function() {
        if (this.visible && this.alpha) {
            var a = !1;
            if (this.angle || 1 != this.alpha || this.shadowColor) N(this),
                a = !0;
            Db(e(this.x, this.y), C(this.w, this.h), this.radius, this.fillColor, this.strokeColor, this.strokeWidth);
            if (this.ondraw) this.ondraw();
            a && H()
        }
    };
    this.game.newRoundRectObject = function(a) { return new Cb(a) };
    var pa = function(a) { B.call(this, a);
        this.radius = a.radius || 5;
        a.scale && (this.radius *= a.scale);
        this.w = 2 * this.radius;
        this.h = 2 * this.radius;
        this.type = "CircleObject";
        a.positionC && this.setPositionC(a.positionC) };
    ba(B, pa);
    pa.prototype.draw = function() {
        if (this.visible && this.alpha) {
            var a = !1;
            if (this.angle || 1 != this.alpha ||
                this.shadowColor) N(this), a = !0;
            Ba(e(this.x, this.y), this.radius, this.fillColor, this.strokeColor, this.strokeWidth);
            if (this.ondraw) this.ondraw();
            a && H()
        }
    };
    pa.prototype.scale = function(a) { this.w *= a || 0;
        this.h *= a || 0;
        this.radius *= a ? a / 2 : 0 };
    pa.prototype.scaleC = function(a) { var b = this.w,
            c = this.h;
        this.w *= a || 0;
        this.h *= a || 0;
        this.radius *= a;
        this.move(e(-((this.w - b) / 2), -((this.h - c) / 2))) };
    pa.prototype.getRadius = function() { return this.radius };
    pa.prototype.setRadius = function(a) {
        a && this.radius != a && (this.radius = a, this.w =
            2 * a, this.h = 2 * a)
    };
    this.game.newCircleObject = function(a) { return new pa(a) };
    var Eb = function(a) {
        this.file = a.file;
        this.w = a.w;
        this.h = a.h;
        this.read = { x: 0, y: 0, w: 0, h: 0 };
        a.read && (this.read.w = a.read.w || 0, this.read.h = a.read.h || 0, this.read.x = a.read.x || 0, this.read.y = a.read.y || 0);
        this.countX = a.countX;
        this.countY = a.countY;
        this.fullW = this.countX * this.w;
        this.fullH = this.countY * this.h;
        this.cnv = g.document.createElement("canvas");
        this.cnv.width = this.w;
        this.cnv.height = this.h;
        this.ctx = this.cnv.getContext("2d");
        this.loaded = !1;
        this.x = a.x || 0;
        this.y = a.y || 0;
        a = g.document.createElement("img");
        var b = this;
        a.onload = function() { b.ctx.drawImage(this, b.read.x ? b.read.x : 0, b.read.y ? b.read.y : 0, b.read.w ? b.read.w : this.width, b.read.h ? b.read.h : this.height, 0, 0, b.w, b.h);
            b.loaded = !0;
            A.load() };
        a.src = this.file;
        A.add()
    };
    Eb.prototype.draw = function() {
        if (this.loaded) {
            var a = -f.x + this.x,
                b = -f.y + this.y,
                c, d;
            for (d = 0; d < this.countY; d += 1)
                if (!(this.y + d * this.h + this.h < f.y || this.y + d * this.h > f.y + p))
                    for (c = 0; c < this.countX; c += 1) this.x + c * this.w + this.w < f.x || this.x +
                        c * this.w > f.x + l || h.drawImage(this.cnv, a + c * this.w, b + d * this.h, this.w, this.h)
        }
    };
    Eb.prototype.getSize = function() { return this.loaded ? C(this.fullW, this.fullH) : C() };
    this.game.newBackgroundObject = function(a) { return new Eb(a) };
    var Fb = function(a) { B.call(this, a);
        this.type = "EllipsObject" };
    ba(B, Fb);
    Fb.prototype.draw = function() { if (this.visible && this.alpha) { N(this);
            Ba(e(this.x, this.y), this.h / 2, this.fillColor, this.strokeColor, this.strokeWidth); if (this.ondraw) this.ondraw();
            H() } };
    this.game.newEllipsObject = function(a) { return new Fb(a) };
    var Z = function(a) { B.call(this, a);
        this.type = "TextObject";
        this.text = a.text || "TextObject";
        this.color = a.color || "";
        this.size = a.size || 10;
        a.scale && (this.size *= a.scale);
        this.font = a.font || "sans-serif";
        this.style = a.style || "";
        this.align = "left";
        this.padding = a.padding || 2;
        this.w = Gb(this.text, this.style, this.size, this.font) + 2 * this.padding;
        this.h = this.size + 2 * this.padding;
        this.strokeColorText = a.strokeColorText || !1;
        this.strokeWidthText = a.strokeWidthText || !1;
        this.textDY = -this.size / 7;
        a.positionC && this.setPositionC(a.positionC) };
    ba(B, Z);
    Z.prototype.reStyle = function(a) {
        this.text = a.text || this.text;
        this.color = a.color || this.color;
        this.size = a.size || this.size;
        this.font = a.font || this.font;
        this.style = a.style || this.style;
        this.padding = a.padding || this.padding;
        this.w = Gb(this.text, this.style, this.size, this.font) + 2 * this.padding;
        this.h = this.size + 2 * this.padding;
        this.strokeColorText = a.strokeColorText || this.strokeColorText;
        this.strokeWidthText = a.strokeWidthText || this.strokeWidthText;
        this.strokeColor = a.strokeColor || this.strokeColor;
        this.strokeWidth =
            a.strokeWidth || this.strokeWidth;
        this.fillColor = a.fillColor || this.fillColor;
        this.textDY = -this.size / 7
    };
    Z.prototype.setText = function(a) { this.text != a && this.reStyle({ text: a }) };
    Z.prototype.getText = function() { return this.text };
    Z.prototype.draw = function() {
        if (this.visible && this.alpha) {
            var a = !1;
            if (this.angle || 1 != this.alpha || this.shadowColor) N(this), a = !0;
            (this.fillColor || this.strokeColor) && Aa(e(this.x, this.y), C(this.w, this.h), this.fillColor, this.strokeColor, this.strokeWidth);
            qa(e(this.x + this.padding, this.textDY +
                this.y + this.padding), this.text, this.color, this.size, this.font, this.style, this.align, this.strokeColorText, this.strokeWidthText);
            if (this.ondraw) this.ondraw();
            a && H()
        }
    };
    Z.prototype.scale = function(a) { this.reStyle({ size: this.size * a }) };
    Z.prototype.scaleC = function(a) { var b = this.w,
            c = this.h;
        this.reStyle({ size: this.size * a });
        this.move(e(-((this.w - b) / 2), -((this.h - c) / 2))) };
    Z.prototype.setSize = function(a) { this.size != a && this.reStyle({ size: a }) };
    Z.prototype.setSizeC = function(a) {
        this.size != a && (this.reStyle({ size: a }),
            this.move(e(-a / 2, -a / 2)))
    };
    var Gb = function(a, b, c, d) { var e = g.document.createElement("canvas").getContext("2d");
        e.font = b + c + "px " + d; return e.measureText(a).width };
    this.OOP.getTextWidth = function(a) { return Gb(a.text, a.style || "", a.size || 10, a.font || "sans-serif") };
    this.game.newTextObject = function(a) { return new Z(a) };
    var Q = function(a) { B.call(this, a);
        this.type = "PolygonObject";
        this.points = [];
        this.dX = this.dY = 0; var b = this;
        a.points && v(a.points, function(a) { b.addPoint(a) });
        this.pointColor = a.pointColor || !1 };
    ba(B, Q);
    Q.prototype.addPoint = function(a) { this.dY = this.dX = 0; var b = this;
        this.y + a.y < this.y && (this.dY = Math.abs(this.y + a.y - this.y), v(this.points, function(a) { a.y += b.dY }));
        this.x + a.x < this.x && (this.dX = Math.abs(this.x + a.x - this.x), b = this, v(this.points, function(a) { a.x += b.dX }));
        this.points.push(e(a.x + this.dX, a.y + this.dY));
        this.h = this.w = 0;
        b = this;
        v(this.points, function(a) { b.h += b.y + a.y > b.y + b.h ? a.y - b.h : 0;
            b.w += b.x + a.x > b.x + b.w ? a.x - b.w : 0 }) };
    Q.prototype.delPoint = function(a) {
        var b, c = this.getPoints();
        this.clearPoints();
        var d =
            0;
        for (b = c.length; d < b; d += 1) d != a && this.addPoint(c[d])
    };
    Q.prototype.clearPoints = function() { this.points = [];
        this.count = 0 };
    Q.prototype.getPoints = function() { return this.points };
    Q.prototype.getCount = function() { return this.points.length };
    Q.prototype.getPoint = function(a) { return this.points[a] };
    Q.prototype.scale = function(a) { return !1 };
    Q.prototype.drawDynamicBox = function(a) {
        var b = !1;
        if (this.angle || 1 != this.alpha || this.shadowColor) N(this), b = !0;
        Na(this.x, this.y, this.points, this.fillColor, a || "yellow", 2, "red");
        b &&
            H()
    };
    Q.prototype.getDynamicBox = function() { var a = []; if (this.angle) { var b = this.getPosition(1);
            c = this;
            v(this.points, function(d) { a.push(E(ua(d, e(c.x, c.y)), b, c.getAngle())) }) } else { var c = this;
            v(this.points, function(b) { a.push(ua(b, e(c.x, c.y))) }) } return a };
    Q.prototype.draw = function() {
        if (this.visible && this.alpha) {
            var a = !1;
            if (this.angle || 1 != this.alpha || this.shadowColor) N(this), a = !0;
            Na(this.x, this.y, this.points, this.fillColor, this.strokeColor, this.strokeWidth, this.pointColor);
            if (this.ondraw) this.ondraw();
            a &&
                H()
        }
    };
    this.game.newPolygonObject = function(a) { return new Q(a) };
    var ra = function(a) { B.call(this, a);
        this.type = "ImageObject";
        this.loaded = !1;
        this.file = "";
        this.forOnLoad = a.onload || !1;
        hc(a.file, this, a.scale || 1) };
    ba(B, ra);
    ra.prototype.draw = function() { if (this.visible && this.alpha && this.loaded) { var a = !1; if (this.angle || 1 != this.alpha || this.shadowColor || this.flip.x || this.flip.y) N(this), a = !0;
            ic(e(this.x, this.y), C(this.w, this.h), this.file); if (this.ondraw) this.ondraw();
            a && H() } };
    ra.prototype.simpleDraw = function(a) {
        if (this.loaded) {
            var b = !1;
            if (this.angle || 1 != this.alpha || this.shadowColor) N(this), b = !0;
            ic(e(a.x, a.y), C(this.w, this.h), this.file);
            b && H()
        }
    };
    ra.prototype.setImage = function(a, b) { this.file != a && (u(k[a]) ? (this.file = a, b && b()) : (this.loaded = !1, this.origHeight = this.origWidth = 0, this.forOnLoad = b || !1, hc(a, this))) };
    ra.prototype.getImage = function() { return this.file };
    ra.prototype.resize = function(a) {
        if (!1 !== a.w && !1 === a.h) { var b = a.w / this.w;
            this.w = a.w;
            this.h *= b } else !1 !== a.h && !1 === a.w ? (b = a.h / this.h, this.h = a.h, this.w *= b) : !1 !== a.w && !1 !== a.h &&
            (this.w = a.w, this.h = a.h)
    };
    this.game.newImageObject = function(a) { return new ra(a) };
    var W = function(a) { B.call(this, a);
        this.type = "AnimationObject";
        this.frame = 0;
        this.anim = a.animation;
        this.step = a.delay || 10;
        this.toFrameStep = this.difStep = 0;
        a.scale && (this.w *= a.scale, this.h *= a.scale) };
    ba(B, W);
    W.prototype.draw = function() {
        if (this.visible && this.alpha) {
            var a = !1;
            if (this.angle || 1 != this.alpha || this.flip.x || this.flip.y || this.shadowColor) N(this), a = !0;
            Hb(this.anim, e(this.x, this.y), C(this.w, this.h), this.frame);
            if (this.ondraw) this.ondraw();
            this.difStep > this.step ? (this.frame = this.frame < this.anim.r ? this.frame + 1 : 0, this.difStep = 0) : this.difStep += 1;
            a && H()
        }
    };
    W.prototype.drawFrames = function(a, b, c) {
        if (this.visible && this.alpha) {
            if (this.frame < a || this.frame > b) this.frame = a;
            c = !1;
            if (this.angle || 1 != this.alpha || this.flip.x || this.flip.y || this.shadowColor) N(this), c = !0;
            Hb(this.anim, e(this.x, this.y), C(this.w, this.h), this.frame);
            if (this.ondraw) this.ondraw();
            this.difStep > this.step ? (this.frame = this.frame < b ? this.frame + 1 : a, this.difStep = 0) : this.difStep += 1;
            c &&
                H()
        }
    };
    W.prototype.drawFrame = function(a) { if (this.visible && this.alpha) { var b = !1; if (this.angle || 1 != this.alpha || this.flip.x || this.flip.y || this.shadowColor) N(this), b = !0;
            Hb(this.anim, e(this.x, this.y), C(this.w, this.h), a); if (this.ondraw) this.ondraw();
            b && H() } };
    W.prototype.drawToFrame = function(a) {
        if (this.visible && this.alpha) {
            if (this.frame < a) this.toFrameStep = 1;
            else if (this.frame > a) this.toFrameStep = -1;
            else { this.drawFrame(a); return } this.drawFrame(this.frame);
            if (this.ondraw) this.ondraw();
            this.difStep > this.step ?
                (this.frame = this.frame < this.anim.r ? this.frame + this.toFrameStep : 0, this.difStep = 0) : this.difStep += 1
        }
    };
    W.prototype.drawReverFrames = function(a, b) { if (this.visible && this.alpha) { this.drawFrame(this.frame); if (this.ondraw) this.ondraw();
            this.difStep > this.step ? (this.frame <= a ? this.toFrameStep = 1 : this.frame >= b && (this.toFrameStep = -1), this.frame += this.toFrameStep, this.difStep = 0) : this.difStep += 1 } };
    W.prototype.setAnimation = function(a) { a.id != this.anim.id && (this.frame = 0, this.anim = a) };
    W.prototype.getAnimation = function() { return this.anim };
    W.prototype.setDelay = function(a) { this.step = 0 < a ? a : this.step };
    W.prototype.getDelay = function() { return this.step };
    this.game.newAnimationObject = function(a) { return new W(a) };
    var $b = function(a) {
            var b = !1;
            "RectObject" == a.type ? b = q.game.newRectObject({}) : "CircleObject" == a.type ? b = q.game.newCircleObject({}) : "RoundRectObject" == a.type ? b = q.game.newRoundRectObject({}) : "TextObject" == a.type ? b = q.game.newTextObject({}) : "EllipsObject" == a.type ? b = q.game.newEllipsObject({}) : "ImageObject" == a.type ? b = q.game.newImageObject({ file: a.file }) :
                "TriangleObject" == a.type ? b = q.game.newTriangleObject({}) : "AnimationObject" == a.type && (b = q.game.newAnimationObject({ animation: a.animation }));
            return b
        },
        Ac = 0,
        sa = function(a, b) {
            this.file = a;
            this.loaded = !1;
            this.h = this.w = 0;
            this.id = Ac++;
            this.toLoad = [];
            var c = g.document.createElement("img"),
                d = this;
            c.onload = function() {
                d.loaded = !0;
                d.w = this.width;
                d.h = this.height;
                d.img = g.document.createElement("canvas");
                d.img.width = this.width;
                d.img.height = this.height;
                d.context = d.img.getContext("2d");
                d.context.drawImage(this, 0, 0);
                d.toLoad.length && v(d.toLoad, function(a) { a.func(d.context, a.w, a.h, a.r) });
                b && (d.onLoad = b, d.onLoad());
                A.load()
            };
            c.src = a;
            A.add()
        };
    sa.prototype.onContext = function(a) { this.loaded ? a(this.context, this.w, this.h, 1) : this.toLoad.push({ w: this.w, h: this.h, r: 1, func: a }) };
    sa.prototype.getCanvas = function() { return this.img };
    var Bc = 0;
    sa.prototype.getAnimation = function(a, b, c, d, e) {
        var n = function(a, b, c, d, e, n) {
            this.id = Bc++;
            this.image = a;
            this.x = b;
            this.y = c;
            this.w = d;
            this.h = e;
            this.endFrame = this.r = n ? n - 1 : 0;
            this.frameCount = this.r +
                1
        };
        n.prototype = { onContext: function(a) { this.image.loaded ? a(this.image.context, this.w, this.h, this.r) : this.image.toLoad.push({ w: this.w, h: this.h, r: this.r, func: a }) }, getImage: function() { return this.image }, getCount: function() { return this.r } };
        return new n(this, a, b, c, d, e)
    };
    var Ib = function(a, b) { this.loaded = !0;
        this.w = a;
        this.h = b;
        this.img = g.document.createElement("canvas");
        this.img.width = a;
        this.img.height = b;
        this.context = this.img.getContext("2d") };
    Ib.prototype.onContext = sa.prototype.onContext;
    Ib.prototype.getAnimation =
        sa.prototype.getAnimation;
    this.tiles.newDrawImage = function(a, b) { return new Ib(a, b) };
    this.tiles.newImage = function(a, b) { return new sa(a, b) };
    this.tiles.newAnimation = function(a, b, c, d) { return (new sa(a)).getAnimation(0, 0, b, c, d) };
    var Hb = function(a, b, c, d) { if (a && a.image.loaded) { var e = -f.x,
                    g = -f.y;
                a.image.img && h.drawImage(a.image.img, a.x + a.w * d, a.y, a.w, a.h, b.x + e, b.y + g, c.w, c.h) } },
        k = {},
        hc = function(a, b, c) {
            if (u(k[a])) {
                b.loaded = !0;
                b.file = a;
                if (b.w && !b.h) { var d = b.w / k[a].w; var e = b.w; var f = k[a].h * d } else !b.w && b.h ? (d = b.h /
                    k[a].h, f = b.h, e = k[a].w * d) : b.w && b.h ? (e = b.w, f = b.h) : (e = k[a].w, f = k[a].h);
                c && (e *= c, f *= c);
                b.w = e;
                b.h = f;
                b.forOnLoad && b.forOnLoad()
            } else e = g.document.createElement("img"), e.onload = function() { k[a] = {};
                    k[a].loaded = !0;
                    k[a].img = this;
                    k[a].w = this.width;
                    k[a].h = this.height; if (u(b)) { b.loaded = !0; if (b.w && !b.h) { var d = b.w / k[a].w; var e = b.w; var f = k[a].h * d } else !b.w && b.h ? (d = b.h / k[a].h, f = b.h, e = k[a].w * d) : b.w && b.h ? (e = b.w, f = b.h) : (e = k[a].w, f = k[a].h);
                        c && (e *= c, f *= c);
                        b.w = e;
                        b.h = f;
                        b.file = a;
                        b.forOnLoad && b.forOnLoad() } A.load() }, e.src = a,
                A.add()
        },
        ic = function(a, b, c) { if (c) { var d = -f.x,
                    e = -f.y;
                k[c] && h.drawImage(k[c].img, 0, 0, k[c].w, k[c].h, a.x + d, a.y + e, b.w, b.h) } },
        jc = function(a) { this.type = "Mesh";
            this.objs = [];
            this.x = a.x || 0;
            this.y = a.y || 0;
            this.angle = a.angle || 0;
            this.count = 0; var b = this;
            a.add && v(a.add, function(a) { b.add(a) });
            this.angle && this.setAngle(this.angle) };
    jc.prototype = {
        getCount: function() { return this.count },
        getObjects: function() { return this.objs },
        add: function(a) {
            this.count += 1;
            this.objs.push(a);
            a.offsetMesh = a.getPosition(1);
            a.turn(this.angle);
            a.setPositionC(e(this.x + a.offsetMesh.x, this.y + a.offsetMesh.y))
        },
        del: function(a) { var b = this;
            v(this.objs, function(c) { c.id == a.id && (b.objs.splice(void 0, 1), b.count--) }) },
        draw: function(a) { v(this.objs, function(a) { a.draw() }) },
        move: function(a) { this.x += a.x || 0;
            this.y += a.y || 0; var b = this;
            v(this.objs, function(a) { a.setPositionC(e(b.x + a.offsetMesh.x, b.y + a.offsetMesh.y)) }) },
        turn: function(a) {
            if (0 != a) {
                this.angle %= 360;
                this.angle += a;
                var b = e(this.x, this.y),
                    c = this;
                v(this.objs, function(d) {
                    d.turn(a);
                    d.setPositionC(E(e(c.x +
                        d.offsetMesh.x, c.y + d.offsetMesh.y), b, c.angle))
                })
            }
        },
        setAngle: function(a) { if (a != this.angle) { this.angle = a %= 360; var b = e(this.x, this.y),
                    c = this;
                v(this.objs, function(d) { d.setAngle(a);
                    d.setPositionC(E(e(c.x + d.offsetMesh.x, c.y + d.offsetMesh.y), b, c.angle)) }) } },
        setPosition: function(a) {
            if (this.x != a.x || this.y != a.y) {
                this.x = a.x || this.x;
                this.y = a.y || this.y;
                var b = this;
                v(this.objs, function(a) {
                    b.angle ? a.setPositionC(E(e(b.x + a.offsetMesh.x, b.y + a.offsetMesh.y), e(b.x, b.y), b.angle)) : a.setPositionC(e(b.x + a.offsetMesh.x, b.y +
                        a.offsetMesh.y))
                })
            }
        },
        isDynamicIntersect: function(a) { if (3 > a.length) return !1; var b = !1;
            v(this.objs, function(c) { if (c.isDynamicIntersect(a)) return b = c }); return b },
        isStaticIntersect: function(a) { var b = !1;
            v(this.objs, function(c) { if (c.isStaticIntersect(a)) return b = c }); return b },
        isIntersect: function(a) { var b = !1;
            v(this.objs, function(c) { if (c.isIntersect(a)) return b = c }); return b }
    };
    this.game.newMesh = function(a) { return new jc(a) };
    this.camera.setScale = function(a) {};
    this.camera.circling = function(a, b, c) {
        u(this.circlingAnglePointJS) ||
            (this.circlingAnglePointJS = c);
        f.x = a.x + b * Math.cos(x(this.circlingAnglePointJS));
        f.y = a.y + b * Math.sin(x(this.circlingAnglePointJS));
        this.circlingAnglePointJS = 360 <= this.circlingAnglePointJS ? c : this.circlingAnglePointJS + c
    };
    this.camera.circlingC = function(a, b, c) {
        u(this.circlingAnglePointJS) || (this.circlingAnglePointJS = c);
        f.x = -O + a.x + b * Math.cos(x(this.circlingAnglePointJS));
        f.y = -P + a.y + b * Math.sin(x(this.circlingAnglePointJS));
        this.circlingAnglePointJS = 360 <= this.circlingAnglePointJS ? c : this.circlingAnglePointJS +
            c
    };
    this.camera.motion = function(a, b, c) { u(this.motionPercentPointJS) || (this.motionPercentPointJS = b);
        f.x = a.x + b.w * Math.cos(x(this.motionPercentPointJS));
        f.y = a.y + b.h * Math.sin(x(this.motionPercentPointJS));
        this.motionPercentPointJS = 360 <= this.motionPercentPointJS ? b : this.motionPercentPointJS + c };
    this.camera.motionC = function(a, b, c) {
        u(this.motionPercentPointJS) || (this.motionPercentPointJS = b);
        this.setPositionC(e(a.x + b.w * Math.cos(x(this.motionPercentPointJS)), a.y + b.h * Math.sin(x(this.motionPercentPointJS))));
        this.motionPercentPointJS =
            360 <= this.motionPercentPointJS ? b : this.motionPercentPointJS + c
    };
    this.camera.follow = function(a) { this.moveTimeC(a.getPositionC(), 10) };
    this.camera.move = function(a) { f.x += a.x || 0;
        f.y += a.y || 0 };
    this.camera.moveTime = function(a, b) { b = b || 1; var c = e(f.x, f.y);
        this.move(e((a.x - c.x) / b, (a.y - c.y) / b)) };
    this.camera.moveTimeC = function(a, b) { b = b || 1; var c = e(f.x + O, f.y + P);
        this.move(e((a.x - c.x) / b, (a.y - c.y) / b)) };
    this.camera.setPosition = function(a) { zb(e(!1 !== a.x ? a.x : f.x, !1 !== a.y ? a.y : f.y)) };
    this.camera.setPositionC = function(a) {
        zb(e(!1 !==
            a.x ? a.x - O : f.x, !1 !== a.y ? a.y - P : f.y))
    };
    this.camera.getPosition = function(a) { return a ? e(f.x + O, f.y + P) : e(f.x, f.y) };
    this.camera.getPositionC = function() { return e(f.x + O, f.y + P) };
    this.camera.getStaticBox = function() { return { x: f.x, y: f.y, w: f.x + l, h: f.y + p } };
    this.camera.getDynamicBox = function() { return [e(f.x, f.y), e(f.x + l, f.y), e(f.x + l, f.y + p), e(f.x, f.y + p)] };
    var zb = function(a) { f = e(a.x, a.y) },
        H = function(a) {
            h.restore();
            h.globalAlpha = t.globalAlpha;
            h.fillStyle = "black";
            h.strokeStyle = "black";
            h.msImageSmoothingEnabled = Da;
            h.imageSmoothingEnabled =
                Da
        },
        N = function(a, b) {
            h.save();
            var c = a.getPositionC();
            a.angle && (h.translate(-f.x + c.x, -f.y + c.y), h.rotate(x(a.angle)), h.translate(-c.x + f.x, -c.y + f.y));
            1 != a.alpha && (h.globalAlpha = a.alpha);
            if (a.flip.x || a.flip.y) h.translate(-f.x + c.x, -f.y + c.y), h.scale(a.flip.x ? -1 : 1, a.flip.y ? -1 : 1), h.translate(-c.x + f.x, -c.y + f.y);
            a.shadowColor && (h.shadowBlur = a.shadowBlur, h.shadowColor = a.shadowColor, h.shadowOffsetX = a.shadowX, h.shadowOffsetY = a.shadowY);
            if ("EllipsObject" == a.type && !b) {
                c = a.w / 2;
                var d = a.h / 2,
                    n = e(-f.x + a.x, -f.y + a.y);
                h.translate(n.x,
                    n.y);
                h.scale(c / d, 1);
                h.translate(-n.x, -n.y)
            }
        };
    this.system.setContextSettings = function(a) { h.save(); for (var b in a) h[b] = a[b] };
    this.system.defaultSettings = function() { H() };
    this.game.clear = function() { h.clearRect(0, 0, l, p) };
    this.game.fill = function(a) { h.fillStyle = a;
        h.fillRect(0, 0, l, p) };
    var Na = function(a, b, c, d, n, g, k) {
            if (!(3 > c.length)) {
                if (d && !(3 > c.length)) { h.fillStyle = d;
                    d = -f.x + a; var l = -f.y + b; var m;
                    h.beginPath();
                    h.moveTo(d + c[0].x, l + c[0].y); for (m = 1; m < c.length; m += 1) h.lineTo(d + c[m].x, l + c[m].y);
                    h.closePath();
                    h.fill() }
                for (d =
                    0; d < c.length; d += 1) l = d + 1 < c.length ? d + 1 : 0, n && aa(ua(c[d], e(a, b)), ua(c[l], e(a, b)), n, g), k && kb(ua(c[d], e(a, b)), k)
            }
        },
        R = function(a) { a.x || (a.x = 0);
            a.y || (a.y = 0);
            a.w || (a.w = 0);
            a.h || (a.h = 0) };
    this.brush.drawPolygon = function(a) {
        var b = a.points || [],
            c = a.fillColor || !1,
            d = a.strokeColor || !1,
            e = a.strokeWidth || 1;
        a = a.pointColor || !1;
        if (!(3 > b.length)) {
            if (c && !(3 > b.length)) { h.fillStyle = c;
                c = -f.x; var g = -f.y; var k;
                h.beginPath();
                h.moveTo(c + b[0].x, g + b[0].y); for (k = 1; k < b.length; k += 1) h.lineTo(c + b[k].x, g + b[k].y);
                h.closePath();
                h.fill() }
            for (c =
                0; c < b.length; c += 1) g = c + 1 < b.length ? c + 1 : 0, d && aa(b[c], b[g], d, e), a && kb(b[c], a)
        }
    };
    this.brush.drawTriangle = function(a) { R(a); if (a.x + a.w < f.x || a.x > f.x + l || a.y + a.h < f.y || a.y > f.y + p) return !1;
        Na(a.x, a.y, [e(a.w / 2, 0), e(a.w, a.h), e(0, a.h)], a.fillColor, a.strokeColor, a.strokeWidth) };
    this.brush.drawTriangleS = function(a) { R(a); if (0 > a.x + a.w || a.x > l || 0 > a.y + a.h || a.y > p) return !1;
        Na(f.x + a.x, f.y + a.y, [e(a.w / 2, 0), e(a.w, a.h), e(0, a.h)], a.fillColor, a.strokeColor, a.strokeWidth) };
    var qa = function(a, b, c, d, e, g, k, l, m) {
        h.textAlign = k;
        h.lineWidth =
            m;
        h.font = (g ? g + " " : "") + d + "px " + e;
        d = -f.x;
        e = -f.y;
        c && (h.fillStyle = c, h.fillText(b, d + a.x, e + a.y));
        l && (h.strokeStyle = l, h.strokeText(b, d + a.x, e + a.y))
    };
    this.brush.drawMultiText = function(a) { var b, c = a.text.split("\n"); for (b = 0; b < c.length; b += 1) qa(e(a.x, a.y + a.size * b), c[b], a.color || t.fillStyle, a.size || 10, a.font || t.font, a.style || !1, a.align || "left", a.strokeColor || !1, a.strokeWidth || 2) };
    this.brush.drawMultiTextS = function(a) {
        var b, c = a.text.split("\n"),
            d = a.size || 10;
        for (b = 0; b < c.length; b += 1) qa(e(a.x + f.x, a.y + f.y + d * b), c[b],
            a.color || t.fillStyle, d || 10, a.font || t.font, a.style || !1, a.align || "left", a.strokeColor || !1, a.strokeWidth || 2)
    };
    this.brush.drawText = function(a) { qa(e(a.x || 0, a.y || 0), a.text, a.color || !1, a.size || 10, a.font || t.font, a.style || !1, a.align || "left", a.strokeColor || !1, a.strokeWidth || 2) };
    this.brush.drawTextS = function(a) { qa(e((a.x || 0) + f.x, (a.y || 0) + f.y), a.text, a.color || t.fillStyle, a.size || 10, a.font || t.font, a.style || !1, a.align || "left", a.strokeColor || !1, a.strokeWidth || 2) };
    this.brush.drawTextLines = function(a) {
        if (a.lines) {
            var b,
                c = a.size || 10;
            for (b = 0; b < a.lines.length; b += 1) qa(e(a.x, a.y + c * b), a.lines[b], a.color || t.fillStyle, c, a.font || t.font, a.style || !1, a.align || "left", a.strokeColor || !1, a.strokeWidth || 2)
        }
    };
    this.brush.drawTextLinesS = function(a) { if (a.lines) { var b, c = a.size || 10; for (b = 0; b < a.lines.length; b += 1) qa(e(a.x + f.x, a.y + f.y + c * b), a.lines[b], a.color || t.fillStyle, c, a.font || t.font, a.style || !1, a.align || "left", a.strokeColor || !1, a.strokeWidth || 2) } };
    var gc = function(a, b, c) {
            aa(e(a.x - b, a.y), e(a.x + b, a.y), c, 2);
            aa(e(a.x, a.y - b), e(a.x, a.y + b),
                c, 2)
        },
        Aa = function(a, b, c, d, e) { h.fillStyle = c;
            h.strokeStyle = d;
            h.lineWidth = e;
            d = -f.x + (e ? e / 2 : 0); var n = -f.y + (e ? e / 2 : 0);
            c && h.fillRect(a.x + d, a.y + n, b.w, b.h);
            e && h.strokeRect(a.x + d, a.y + n, b.w, b.h) };
    this.brush.drawRect = function(a) { R(a); if (a.x + a.w < f.x || a.x > f.x + l || a.y + a.h < f.y || a.y > f.y + p) return !1;
        Aa(e(a.x, a.y), C(a.w, a.h), a.fillColor || !1, a.strokeColor || t.strokeStyle, a.strokeWidth || !1) };
    this.brush.drawRectS = function(a) {
        R(a);
        if (0 > a.x + a.w || a.x > l || 0 > a.y + a.h || a.y > p) return !1;
        Aa(e(a.x + f.x, a.y + f.y), C(a.w, a.h), a.fillColor ||
            !1, a.strokeColor || t.strokeStyle, a.strokeWidth || !1)
    };
    var kb = function(a, b) {
        (h.fillStyle = b) && h.fillRect(-f.x + a.x - 1, -f.y + a.y - 1, 2, 2) };
    this.brush.drawPoint = function(a) { R(a); if (a.x < f.x || a.x > f.x + l || a.y < f.y || a.y > f.y + p) return !1;
        kb(e(a.x, a.y), a.fillColor || !1) };
    this.brush.drawPointS = function(a) { R(a); if (0 > a.x || a.x > l || 0 > a.y || a.y > p) return !1;
        kb(e(a.x + f.x, a.y + f.y), a.fillColor || !1) };
    var Db = function(a, b, c, d, e, g) {
        h.fillStyle = d;
        h.strokeStyle = e;
        h.lineWidth = g;
        e = -f.x + a.x + (g ? g / 2 : 0);
        a = -f.y + a.y + (g ? g / 2 : 0);
        h.beginPath();
        h.moveTo(e +
            c, a);
        h.lineTo(e + b.w - c, a);
        h.quadraticCurveTo(e + b.w, a, e + b.w, a + c);
        h.lineTo(e + b.w, a + b.h - c);
        h.quadraticCurveTo(e + b.w, a + b.h, e + b.w - c, a + b.h);
        h.lineTo(e + c, a + b.h);
        h.quadraticCurveTo(e, a + b.h, e, a + b.h - c);
        h.lineTo(e, a + c);
        h.quadraticCurveTo(e, a, e + c, a);
        h.closePath();
        d && h.fill();
        g && h.stroke()
    };
    this.brush.drawRoundRect = function(a) { R(a); if (a.x + a.w < f.x || a.x > f.x + l || a.y + a.h < f.y || a.y > f.y + p) return !1;
        Db(e(a.x, a.y), C(a.w, a.h), a.radius || 2, a.fillColor || !1, a.strokeColor || t.strokeStyle, a.strokeWidth || !1) };
    this.brush.drawRoundRectS =
        function(a) { R(a); if (0 > a.x + a.w || a.x > l || 0 > a.y + a.h || a.y > p) return !1;
            Db(e(f.x + a.x, f.y + a.y), C(a.w, a.h), a.radius || 2, a.fillColor || !1, a.strokeColor || t.strokeStyle, a.strokeWidth || !1) };
    var Ba = function(a, b, c, d, e) { h.fillStyle = c;
        h.strokeStyle = d;
        h.lineWidth = e;
        d = -f.x + b + (e ? e / 2 : 0); var g = -f.y + b + (e ? e / 2 : 0);
        h.beginPath();
        h.arc(a.x + d, a.y + g, b, 0, 2 * Math.PI, !0);
        h.closePath();
        c && h.fill();
        e && h.stroke() };
    this.brush.drawCircle = function(a) {
        R(a);
        var b = 2 * a.radius;
        if (a.x + b < f.x || a.x > f.x + l || a.y + b < f.y || a.y > f.y + p) return !1;
        Ba(e(a.x, a.y),
            a.radius, a.fillColor || !1, a.strokeColor || t.strokeStyle, a.strokeWidth || !1)
    };
    this.brush.drawCircleS = function(a) { R(a); var b = 2 * a.radius; if (0 > a.x + b || a.x > l || 0 > a.y + b || a.y > p) return !1;
        Ba(e(a.x + f.x, a.y + f.y), a.radius, a.fillColor || !1, a.strokeColor || t.strokeStyle, a.strokeWidth || !1) };
    var aa = function(a, b, c, d) { h.strokeStyle = c;
        h.lineWidth = d;
        c = -f.x;
        d = -f.y;
        h.beginPath();
        h.moveTo(c + a.x, d + a.y);
        h.lineTo(c + b.x, d + b.y);
        h.closePath();
        h.stroke() };
    this.brush.drawLineAngle = function(a) {
        var b = E(e(a.x + a.length, a.y), e(a.x, a.y), a.angle);
        aa(e(a.x, a.y), e(b.x, b.y), a.strokeColor || t.strokeStyle, a.strokeWidth || 1)
    };
    this.brush.drawLineAngleS = function(a) { var b = E(e(f.x + a.x + a.length, f.y + a.y), e(f.x + a.x, f.y + a.y), a.angle);
        aa(e(f.x + a.x, f.y + a.y), e(b.x, b.y), a.strokeColor || t.strokeStyle, a.strokeWidth || 1) };
    this.brush.drawLine = function(a) { aa(e(a.x1, a.y1), e(a.x1 + a.x2, a.y1 + a.y2), a.strokeColor || t.strokeStyle, a.strokeWidth || 1) };
    this.brush.drawLineS = function(a) { aa(e(f.x + a.x1, f.y + a.y1), e(f.x + a.x2, f.y + a.y2), a.strokeColor || t.strokeStyle, a.strokeWidth || 1) };
    this.brush.drawLineA = function(a) { aa(e(a.x1, a.y1), e(a.x2, a.y2), a.strokeColor || t.strokeStyle, a.strokeWidth || 1) };
    this.brush.drawLineAS = function(a) { aa(e(a.x1 + f.x, a.y1 + f.y), e(a.x2 + f.x, a.y2 + f.y), a.strokeColor || t.strokeStyle, a.strokeWidth || 1) };
    this.brush.drawEllips = function(a) {
        R(a);
        if (a.x + a.w < f.x || a.x > f.x + l || a.y + a.h < f.y || a.y > f.y + p) return !1;
        var b = a.w / 2,
            c = a.h / 2,
            d = e(-f.x + a.x, -f.y + a.y);
        h.save();
        h.translate(d.x, d.y);
        h.scale(b / c, 1);
        h.translate(-d.x, -d.y);
        Ba(e(a.x, a.y), c, a.fillColor, a.strokeColor, a.strokeWidth);
        h.restore()
    };
    this.brush.drawEllipsS = function(a) { R(a); if (0 > a.x + a.w || a.x > l || 0 > a.y + a.h || a.y > p) return !1; var b = a.w / 2,
            c = a.h / 2,
            d = e(a.x, a.y);
        h.save();
        h.translate(d.x, d.y);
        h.scale(b / c, 1);
        h.translate(-d.x, -d.y);
        Ba(e(f.x + a.x, f.y + a.y), c, a.fillColor, a.strokeColor, a.strokeWidth);
        h.restore() };
    this.brush.drawImageS = function(a) {
        if (a.file)
            if (u(k[a.file])) {
                if (k[a.file].loaded) {
                    var b = a.x || 0,
                        c = a.y || 0;
                    if (a.w && !a.h) { var d = a.w / k[a.file].w; var e = a.w; var f = k[a.file].h * d } else !a.w && a.h ? (d = a.h / k[a.file].h, f = a.h, e = k[a.file].w *
                        d) : a.w && a.h ? (e = a.w, f = a.h) : (e = k[a.file].w, f = k[a.file].h);
                    a.scale && (e *= a.scale, f *= a.scale);
                    if (0 > b + e || b > l || 0 > c + f || c > p) return !1;
                    h.drawImage(k[a.file].img, 0, 0, k[a.file].w, k[a.file].h, b, c, e, f)
                }
            } else k[a.file] = { loaded: !1 }, b = g.document.createElement("img"), b.onload = function() { k[a.file].loaded = !0;
                k[a.file].img = this;
                k[a.file].w = this.width;
                k[a.file].h = this.height;
                A.load() }, b.src = a.file, A.add()
    };
    this.brush.drawImage = function(a) {
        if (a.file)
            if (u(k[a.file])) {
                if (k[a.file].loaded) {
                    var b = a.x || 0,
                        c = a.y || 0;
                    if (a.w && !a.h) {
                        var d =
                            a.w / k[a.file].w;
                        var e = a.w;
                        var m = k[a.file].h * d
                    } else !a.w && a.h ? (d = a.h / k[a.file].h, m = a.h, e = k[a.file].w * d) : a.w && a.h ? (e = a.w, m = a.h) : (e = k[a.file].w, m = k[a.file].h);
                    a.scale && (e *= a.scale, m *= a.scale);
                    if (b + e < f.x || b > f.x + l || c + m < f.y || c > f.y + p) return !1;
                    h.drawImage(k[a.file].img, 0, 0, k[a.file].w, k[a.file].h, -f.x + b, -f.y + c, e, m)
                }
            } else k[a.file] = {}, k[a.file].loaded = !1, b = g.document.createElement("img"), b.onload = function() { k[a.file].loaded = !0;
                    k[a.file].img = this;
                    k[a.file].w = this.width;
                    k[a.file].h = this.height;
                    A.load() }, b.src =
                a.file, A.add()
    };
    this.brush.onContext = function(a) { a(h) };
    this.brush.getPixelColor = function(a, b) { var c = h.getImageData(a, b, 1, 1).data; return "rgb(" + c[0] + ", " + c[1] + ", " + c[2] + ")" };
    this.brush.setPixelColor = function(a, b, c) { var d = h.createImageData(1, 1);
        d.data[0] = c.r || d.data[0];
        d.data[1] = c.g || d.data[1];
        d.data[2] = c.b || d.data[2];
        d.data[3] = c.a || 255;
        h.putImageData(d, a, b) };
    this.brush.onPixel = function(a, b, c) {
        var d = h.getImageData(a, b, 1, 1),
            e = { r: d.data[0], g: d.data[1], b: d.data[2], a: d.data[3] ? d.data[3] : 255 };
        c(e);
        d.data[0] =
            e.r;
        d.data[1] = e.g;
        d.data[2] = e.b;
        d.data[3] = e.a;
        h.putImageData(d, a, b)
    };
    this.brush.onPixels = function(a, b, c, d, e) { c = h.getImageData(a, b, c, d); var f;
        d = 0; for (f = c.data.length; d < f; d += 4) { var g = { r: c.data[d], g: c.data[d + 1], b: c.data[d + 2], a: c.data[d + 3] ? c.data[d + 3] : 255 };
            e(g);
            c.data[d] = g.r;
            c.data[d + 1] = g.g;
            c.data[d + 2] = g.b;
            c.data[d + 3] = g.a } h.putImageData(c, a, b) };
    this.brush.onRawPixels = function(a, b, c, d, e) { c = h.getImageData(a, b, c, d);
        e(c.data, c.data.length);
        h.putImageData(c, a, b) };
    var S = g.AudioContext || g.webkitAudioContext ||
        !1;
    (S = S ? new S : !1) && S.listener.setPosition(0, 0, 0);
    var T = function(a, b) {
        S || U('module "wAudio" is not supported! use a "audio"');
        this.vol = b && 1 >= b && 0 < b ? b : 1;
        this.loadPLay = this.nextPlay = this.loaded = this.playing = !1;
        this.pausedTime = this.duration = this.startTime = 0;
        var c = this,
            d = new XMLHttpRequest;
        d.open("GET", a, !0);
        d.responseType = "arraybuffer";
        d.onload = function(a) {
            S.decodeAudioData(this.response, function(a) {
                c.wABuffer = a;
                c.duration = c.wABuffer.duration;
                c.wAGain = S.createGain();
                c.wAGain.gain.value = c.vol;
                c.wAPanner =
                    S.createPanner();
                c.wAPanner.setPosition(0, 0, 1);
                c.wAPanner.panningModel = "equalpower";
                A.load();
                c.loaded = !0;
                c.loadPlay && c.replay()
            }, function(a) { U("error in wAudio.newAudio : error decoding file", a) })
        };
        a ? d.send() : U("error in wAudio.newAudio : Where is file?");
        A.add()
    };
    T.prototype.play = function(a) {
        if (!this.loaded) this.loadPlay = !0;
        else if (!this.playing) {
            this.playing = !0;
            this.wASource = S.createBufferSource();
            this.wASource.buffer = this.wABuffer;
            this.wAListener = S.destination;
            this.wASource.connect(this.wAGain);
            this.wAGain.connect(this.wAPanner);
            this.wAPanner.connect(this.wAListener);
            this.wASource.start(0, this.pausedTime, this.duration);
            this.startTime = S.currentTime;
            var b = this;
            this.wASource.onended = function() { b.playing = !1;
                b.startTime = 0;
                b.pausedTime = 0;
                b.nextPlay && b.nextPlay.replay() }
        }
    };
    T.prototype.replay = function(a) { this.loaded ? (this.stop(), this.play()) : this.loadPlay = !0 };
    T.prototype.stop = function() { this.pause();
        this.pausedTime = this.startTime = 0 };
    T.prototype.pause = function() {
        if (this.playing) {
            this.pausedTime =
                this.getProgress();
            this.playing = !1;
            this.wASource.stop(0);
            var a = this;
            this.wASource.onended = function() { a.playing = !1 }
        }
    };
    T.prototype.getProgress = function() { return this.playing ? S.currentTime - this.startTime + this.pausedTime : this.pausedTime };
    T.prototype.playPause = function() { this.playing ? this.pause() : this.play() };
    T.prototype.setNextPlay = function(a) { this.nextPlay = a };
    T.prototype.setVolume = function(a) { this.vol = a && 1 >= a && 0 < a ? a : this.vol;
        this.wAGain.gain.value = this.vol };
    T.prototype.getVolume = function() { return this.vol };
    T.prototype.setSide = function(a) { this.side = a;
        this.wAPanner && this.wAPanner.setPosition(this.side, 0, 1 - Math.abs(this.side)) };
    T.prototype.getSide = function() { return this.side };
    this.wAudio.newAudio = function(a, b) { return new T(a, b) };
    var da = function(a, b) {
        var c, d = g.document.createElement("audio");
        if ("string" == typeof a) { var e = g.document.createElement("source");
            e.src = a;
            d.appendChild(e) } else { var f = 0; for (c = a.length; f < c; f += 1) e = g.document.createElement("source"), e.src = a[f], d.appendChild(e) } this.vol = b && 1 >= b && 0 < b ? b :
            1;
        this.playing = 0;
        this.audio = d;
        this.nextPlay = this.loaded = !1;
        d.volume = this.vol;
        var h = this;
        d.onloadeddata = function() { h.loaded = !0;
            A.load() };
        d.onended = function() { h.playing = !1;
            h.nextPlay && h.nextPlay.play() };
        d.load();
        A.add()
    };
    da.prototype.play = function(a) { this.playing || (a && (this.vol = a && 1 >= a && 0 < a ? a : this.vol, this.audio.volume = this.vol), this.playing = !0, this.audio.play()) };
    da.prototype.replay = function(a) { a && this.setVolume(a);
        this.playing = !0;
        this.audio.currentTime = 0;
        this.audio.play() };
    da.prototype.stop = function() {
        this.playing &&
            (this.playing = !1, this.audio.pause(), this.audio.currentTime = 0)
    };
    da.prototype.pause = function() { this.playing && (this.playing = !1, this.audio.pause()) };
    da.prototype.playPause = function() { this.playing ? this.pause() : this.play() };
    da.prototype.setNextPlay = function(a) { this.nextPlay = a };
    da.prototype.setVolume = function(a) { this.vol = a && 1 >= a && 0 < a ? a : this.vol;
        this.audio.volume = this.vol };
    da.prototype.getVolume = function() { return this.vol };
    this.audio.newAudio = function(a, b) { return new da(a, b) };
    var lb = [],
        ta = [];
    this.zList.useZValue =
        function() { this.update = function() { ta.length = 0;
                v(lb, function(a) { a.isInCamera() && ta.push(a) });
                ta.sort(function(a, b) { return a.z - b.z }) } };
    this.zList.useYValue = function() { this.update = function() { ta.length = 0;
            v(lb, function(a) { a.isInCamera() && ta.push(a) });
            ta.sort(function(a, b) { return a.y + a.h - (b.y + b.h) }) } };
    this.zList.add = function(a) { lb.push(a) };
    this.zList.init = function(a) { v(a, function(a) { q.zList.add(a) }) };
    this.zList.draw = function(a) { q.OOP.drawArr(ta, a) };
    this.zList.del = function(a) { q.OOP.delObject(lb, a) };
    this.zList.useYValue();
    var A = { count: 0, loaded: 0, errored: 0, add: function() { this.count += 1 }, load: function() { this.loaded += 1 }, error: function() { this.errored += 1 } };
    this.resources.isLoaded = function() { return A.count == A.loaded };
    this.resources.getProgress = function() { return Math.ceil(A.loaded / A.count * 100) };
    this.levels.forStringArray = function(a, b) { var c = a.offset || e(0, 0);
        v(a.source, function(d, e) { v(d, function(d, f) { " " != d && b(d, c.x + a.w * f, c.y + a.h * e, a.w, a.h) }) }) };
    var Cc = function(a) {
            "ImageObject" == a.type && "undefined" != typeof RESOURCES && a.resFile &&
                (a.file = RESOURCES[a.resFile]);
            "AnimationObject" == a.type && "undefined" != typeof ANIMATIONS && a.animId && (a.anim = ANIMATIONS[a.animId]);
            var b = $b(a);
            b.name = "";
            D(a, function(a, d) { "id" != d && (b[d] = a) });
            return b
        },
        kc = function(a, b) { var c = { settings: {}, objects: [] };
            a = JSON.parse(a);
            c.settings = a.settings;
            v(a.objects, function(a) { var d = Cc(a);
                d.name = a.name;
                b && b(d);
                c.objects.push(d) }); return c },
        lc = function(a, b, c) {
            var d = [],
                e = {};
            if (a && "json" == b) { b = kc(a, c);
                d = b.objects;
                e = b.settings; var f = a } this.backgroundColor = e.backgroundColor ?
                e.backgroundColor : !1;
            this.reload = function() { d = kc(f) };
            this.clear = function() { Zb(d) };
            this.add = function(a) { d.push(a) };
            this.del = function(a) { v(d, function(b, c) { if (a.id == b.id) return d.splice(c, 1), "break" }) };
            this.delById = function(a) { d.splice(a, 1) };
            this.getObjects = function() { return d };
            this.getObjectByName = function(a) { var b; var c = 0; for (b = d.length; c < b; c += 1)
                    if (d[c].name == a) return d[c]; return !1 };
            this.getObjectById = function(a) { var b; var c = 0; for (b = d.length; c < b; c += 1)
                    if (d[c].id == a) return d[c]; return !1 };
            this.draw = function(a) {
                this.backgroundColor &&
                    q.game.fill(this.backgroundColor);
                v(d, function(b) { a && a(b);
                    b.draw() })
            };
            this.getLevelAsJSON = function(a, b) { var c = '{"settings":' + JSON.stringify({ backgroundColor: this.backgroundColor }) + ',"objects":['; if (!d.length) return c + "]}";
                v(d, function(d, e) { a && a(d);
                    c += "{";
                    D(d, function(a, b) { "function" != typeof a && (c += '"' + b + '":' + JSON.stringify(a) + ",") });
                    c = c.substr(0, c.length - 1) + "},";
                    b && b(d) });
                c = c.substr(0, c.length - 1); return c + "]}" }
        };
    this.levels.newLevelFromJSON = function(a, b) { return new lc(a, "json", b || !1) };
    this.levels.newEmptyLevel =
        function(a) { return new lc(!1) };
    var mc = 0,
        nc = 0,
        Jb = 0,
        oc = !1;
    this.system.initFPSCheck = function() { oc || (oc = !0, m.addEvent("postLoop", "fpsCheckUpdate", function() { Jb += 1;
            1E3 <= L - nc && (mc = Jb, Jb = 0, nc = L) })) };
    this.system.getFPS = function() { return mc };
    var mb = this.filters;
    mb.setCSSFilter = function(a, b) { var c = (b ? b.canvas : r).style,
            d = "";
        D(a, function(a, b) { d += " " + b + "(" + a + ")" });
        c.OFilter = c.MozFilter = c.WebkitFilter = c.filter = d };
    mb.clearCSSFilter = function(a) {
        a = (a ? a.canvas : r).style;
        a.OFilter = a.MozFilter = a.WebkitFilter = a.filter =
            "none"
    };
    mb.setCSSTransform = function(a, b) { var c = (b ? b.canvas : r).style,
            d = "perspective(" + l + "px)";
        D(a, function(a, b) { d += " " + b + "(" + a + ")" });
        c.transform = c.MozTransform = c.WebkitTransform = d };
    mb.clearCSSTransform = function(a) { a = (a ? a.canvas : r).style;
        a.transform = a.MozTransform = a.WebkitTransform = "none" };
    this.OOP.newRever = function(a, b, c) {
        var d = function(a, b, c) { this.min = a;
            this.max = b;
            this.step = c;
            this.value = a;
            this.to = c };
        d.prototype = {
            update: function() {
                var a = this.value;
                this.value <= this.min ? this.to = this.step : this.value >=
                    this.max && (this.to = -this.step);
                this.value += this.to;
                return a
            },
            getValue: function() { return this.value },
            setValue: function(a) { this.value = parseFloat(a) },
            setStep: function(a) { this.step = a },
            getStep: function() { return this.step }
        };
        return new d(a, b, c)
    };
    var pc = {};
    this.OOP.once = function(a, b) { pc[a] || (pc[a] = !0, b()) };
    this.OOP.newTimer = function(a, b) {
        if (0 >= a) return ja("error in system.newTimer : variable < 0, Timer is not created");
        var c = {
            time: 0 < a ? a : 1E3,
            func: b,
            startTime: !1,
            ending: !1,
            start: function() {
                this.ending || this.startTime ||
                    (this.startTime = L)
            },
            run: function() {!this.ending && this.startTime && L - this.startTime >= this.time && (this.func(), this.ending = !0) },
            end: function() { this.ending || (this.ending = !0, this.func()) },
            restart: function(a) { this.startTime || this.start(); if (this.ending) { if (a && 0 >= a) return ja("error in Timer.restart : variable < 0");
                    a && (this.time = a);
                    this.ending = !1;
                    this.startTime = L } },
            stop: function() { this.ending || (this.ending = !0) }
        };
        m.addEvent("postLoop", "timer" + ca(-100, 100) * ca(-100, 100) + L, function() { c.run() });
        return c
    };
    this.memory.local = { storage: g.localStorage, clear: function() { this.storage.clear() }, save: function(a, b) { this.storage.setItem(a, b) }, saveAsObject: function(a, b) { var c = JSON.stringify(b);
            this.storage.setItem(a, c) }, loadAsObject: function(a) { return JSON.parse(this.storage.getItem(a)) }, load: function(a) { return this.storage.getItem(a) }, loadAsNumber: function(a) { return parseFloat(this.storage.getItem(a)) } };
    this.memory.temp = { values: {}, save: function(a, b) { this.values[a] = b }, load: function(a) { return this.values[a] }, loadAsNumber: function(a) { return parseFloat(this.values[a]) } };
    g.onload = function() { if (h) { for (var a in t) h[a] = t[a];
            h.save() } m.runEvent("onload");
        m.loaded = !0; "function" === typeof POINTJS_USER_ONLOAD && POINTJS_USER_ONLOAD(); return !1 };
    g.onblur = function() { if (ka) return m.runEvent("gameBlur"), !1 };
    g.onfocus = function() { if (!ka) return g.document.activeElement.blur(), g.focus(), m.runEvent("gameFocus"), !1 };
    g.onresize = function() { m.runEvent("gameResize");
        h && (h.textBaseline = t.textBaseline); return !1 };
    g.onclick = function() { g.document.activeElement.blur();
        g.focus() };
    if ("undefined" !==
        typeof POINTJS_LOADED_DOM_IGNORE) g.onload()
};